home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Layout / Frame.cpp < prev    next >
Encoding:
Text File  |  1997-02-13  |  84.8 KB  |  2,878 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Frame.cpp
  3.  
  4.     Contains:    Implementation of ODFrame
  5.  
  6.     Owned by:    Joshua Susser
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.         <15>      12/17/96    CC        1379355: ChangeLinkStatus, EditInLink:
  13.                                     Avoid dispatch on NULL frame window.
  14.         <14>      11/19/96    CC        1354893 Create new frames during move to
  15.                                     simplify in-limbo recipes.
  16.                                     1385977 Refcount leak in ChangeLinkStatus.
  17.         <13>      11/14/96    TJ        #1401258 Fixed the definition of VOID.
  18.         <12>      10/18/96    DM        1393717: incidental ODFrame property
  19.                                     changes need not dirty draft
  20.         <11>      10/10/96    RA        1353949: Invalidate facets during editor
  21.                                     swapping
  22.         <10>     10/4/96    JBS        1308815 ChangeLinkStatus was setting fDirty
  23.                                     when link status didn't change
  24.          <9>     9/24/96    eeh        1315228: Verify part wrapper passed
  25.          <8>     9/23/96    EL        1369173: Root frame of document must not be
  26.                                     frozen
  27.          <7>     6/26/96    eeh        1360132: make limbo focus searching simpler
  28.                                     and more exception-safe.
  29.          <6>     6/25/96    eeh        1360132: force frames to release foci
  30.                                     before being put into limbo.
  31.          <5>     5/30/96    CC        1329275: InitFrameFromStorage: Force link
  32.                                     status to kODNotInLink if root frame of
  33.                                     draft.
  34.          <3>     3/26/96    CC        1329842: kODPropLinkStatus is not a
  35.                                     required property.
  36.          <2>     3/15/96    CC        1329241: InitFrameNonPersistent: Initialize
  37.                                     fLinkStatus.
  38.                                     1329268: ChangeLinkStatus: Look for source
  39.                                     frame if no containing frame.
  40.         <74>     11/2/95    RR        #1298614 Check for NULL su in PrepareToSwap
  41.         <73>     11/1/95    JBS        1289931 GM: move release calls from
  42.                                     somUninit to Release all, use SafeRelease
  43.         <72>    10/24/95    TÇ        Removed two errant semicolons introduced
  44.                                     with fix of #1288922 don't force
  45.                                     DrawActiveBorder, wait for Window::Update
  46.         <71>    10/24/95    jpa        1293441: Ignore exceptions from
  47.                                     DisplayFrame{Closed,Removed}.
  48.         <70>    10/18/95    JBS        1288922 don't force DrawActiveBorder, wait
  49.                                     for Window::Update
  50.         <69>    10/17/95    jpa        1292659: Fixed leaks if parts throw
  51.         <68>     10/9/95    JBS        1290561 GM: ChangeLinkStatus dirties draft
  52.                                     unnecessarily; 1289931 GM: release objects
  53.                                     in ReleaseAll, not somUninit
  54.         <67>     10/8/95    TJ        Fixes Recomended by Refball
  55.         <66>     9/21/95    JBS        1284283 window refcounting in PrepareToSwap
  56.         <65>     9/13/95    DM        1277216 GM:API return no ODPoints nor
  57.                                     ODPolygons
  58.         <64>     9/12/95    JBS        1283657 part->FacedAdded called twice in
  59.                                     Frame::FacetAdded
  60.         <63>      9/8/95    JBS        1281770 Frame::ChangeLinkStatus short
  61.                                     circuits
  62.         <62>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  63.                                     without kOD prefix!
  64.         <61>      9/6/95    VL        1270294: Added and use
  65.                                     kFrameIsInRemoveFrame to avoid recursive
  66.                                     removal. Removed CHECKVALID in GetID.
  67.         <60>     8/31/95    JBS        1278337 error code cleanup
  68.         <59>     8/25/95    JBS        1263078 FB: fix part editor swapping;
  69.                                     1278052 FB: add InLimbo flag
  70.         <58>     8/17/95    CC        1273056: ContentUpdated acquires wrong
  71.                                     part.
  72.         <57>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  73.                                     file.
  74.         <56>     8/12/95    TÇ        1276807 Opt./Bug: use StdTypIO routines for
  75.                                     portable streaming & smaller footprint
  76.         <55>      8/7/95    JBS        1262428 ASSERT in AcquirePart if part NULL;
  77.                                     1265721 don't purge facets' if invalid
  78.         <54>      8/3/95    RR        #1257260: Collapse B classes. Remove
  79.                                     somInit methods. Don't call IsInitialized
  80.                                     or SubclassResponsibility
  81.         <53>     7/27/95    JBS        1231232 SetContainingFrame - remove part
  82.                                     notification
  83.                                     1264303 AcquireContainingFrame - don't lazy
  84.                                     internalize if IsRoot
  85.         <52>     7/27/95    DM        #1270320: Mem leaks: must cast when
  86.                                     assigning from temp ref to another in
  87.                                     EditInLink and ContentUpdated
  88.         <51>     7/26/95    DM        #1270320: Memory leak fixes. delete
  89.                                     typeString returns from GetType in
  90.                                     Externalize and CloneInto
  91.         <50>      7/3/95    RR        1242642 BB: refcounting. SetContainingFrame
  92.                                     needed to Acquire before calling
  93.                                     window->CloseAndRemove.
  94.         <49>     6/29/95    DM        1242642 BB: refcounting: acquire member
  95.                                     vars (not locals) when possible, add
  96.                                     "Acquire" to names of local "ReadIfAny"
  97.                                     functions, release biasTransform    in
  98.                                     InitFrameFromStorage.
  99.         <48>     6/28/95    RR        1242642 BB Mostly ref counting. Release
  100.                                     window in CLose and Remove
  101.         <47>     6/23/95    JBS        1261323 add isSubframe param to InitFrame;
  102.                                     1238245 (done) InitFrame throws error on
  103.                                     non-subframe recursive embed
  104.         <46>     6/23/95    JBS        1251627 fix refcounting throughout file
  105.         <45>     6/21/95    JBS        1238245: (not done) InitFrame check for
  106.                                     recursive embedding; 1243657 SetWindow
  107.                                     throws if not root frame
  108.         <44>     6/20/95    JBS        1257315 change AcquireWindow to GetWindow
  109.         <43>     5/31/95    JBS        1250140 fixed refcount bug in AcquirePart
  110.         <42>     5/26/95    RR        #1251403: Multithreading naming support
  111.         <41>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  112.                                     refcount
  113.         <40>     5/17/95    JBS        1245283 Undoable frame deletion - close
  114.                                     part windows in SetContainingFrame; 1242496
  115.                                     change SOM_CATCH to SOM_TRY; 1250140 bump
  116.                                     refcount in AcquireContainingFrame, AcquirePart,
  117.                                     AcquireWindow
  118.         <39>     5/15/95    JBS        1245156 implement Purge
  119.         <38>      5/5/95    TJ        Put "VOID" into CHECKVALID since #$&* SCpp
  120.                                     won't take empty macro arguments.
  121.         <37>      5/4/95    JBS        1243651 added CHECKVALID to most methods,
  122.                                     and fixed ternalization to respect
  123.                                     fValidState
  124.         <36>     4/27/95    JBS        1209506 $5 comments eliminated
  125.         <35>     4/25/95    JBS        1242496 use SOM_TRY, etc. for exception
  126.                                     handling; 1241983 Externalize assumes
  127.                                     containing frame is persistent; 1183059
  128.                                     throw kODErrIllegalNullStorageUnitInput if
  129.                                     SU is nil; 1242527  AcquireContainingFrame
  130.                                     should not write SU; 1242546  Frame should
  131.                                     compute IsRoot from contFrame
  132.         <34>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  133.                                     should take Environment* and SU* when
  134.                                     possible.  Also Clone a little better to
  135.                                     help out Save A Copy.
  136.         <33>     4/13/95    JBS        1211972 don't mark draft dirty if frame is
  137.                                     non-persistent;1233726 Frame::CloneInto
  138.                                     should call part->ClonePartInfo;1238250
  139.                                     Frame PartInfo should have multiple
  140.                                     values;1237963 don't validate
  141.                                     ContainingFrame property on init
  142.         <32>      4/3/95    CC        1234631: ChangeLinkStatus: Set _fLinkStatus
  143.                                     BEFORE notifying the part!
  144.         <31>     3/28/95    JBS        1229656 implemented EditInLink
  145.         <30>     3/28/95    JBS        1229656 add EditInLink()
  146.         <29>      3/8/95    JBS        1165158 AdjustBorderShape implementation
  147.         <28>     2/24/95    CC        Commented out redefinition of
  148.                                     ODFrameMethodDebug.
  149.         <27>     2/15/95    JBS        1198600 code review cleanup; 1195854 added
  150.                                     SetDirty, dirty/write properties
  151.                                     individually; 1189547 don't allow viewType
  152.                                     and pres to be NULL; 1183059 throw if NULL
  153.                                     su in InitFrameFromStorage; 1206295 don't
  154.                                     externalize UsedShape
  155.         <26>     1/25/95    CC        1206295: (for JBS) Temporarily add
  156.         <25>     1/20/95    JBS        1195017, 1205669: part API changes
  157.         <24>     11/1/94    CC        1196908 - SetContainingFrame: remove all
  158.                                     facets displaying this frame and call
  159.                                     ODPart::FacetRemoved();
  160.                                     FacetRemoved(): Guard against facets not in
  161.                                     the collection of display facets.
  162.                                     somUninit(): Fixed memory leak by deleting
  163.                                     fFacets collection.
  164.         <23>     9/29/94    JBS        1188214: more coord bias impl
  165.         <22>     9/26/94    JBS        1186332, 1188981 - nonpersistence; 1183568
  166.                                     - keep fIsDirty flag
  167.         <21>     9/22/94    JBS        1188214: coordinate bias implementation
  168.         <20>      9/7/94    CC        #1185056 - Use StdTypIO methods to
  169.                                     internalize/externalize fLinkStatus field.
  170.         <19>      9/6/94    CC        1153777- Implement GetLinkStatus(),
  171.                                     ChangeLinkStatus(), and ContentUpdated(),
  172.                                     and maintain the persistent fLinkStatus
  173.                                     field.
  174.         <18>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  175.                                     Lots of ErrorCode cleanup.
  176.         <17>     8/31/94    VL        1183174: Fixed CloneInto to avoid multiple
  177.                                     cloning. Removed CloneTo which was
  178.                                     commented out in <14>. Removed CMDraft.xh
  179.                                     because we are not depending on it with the
  180.                                     new cloning mechanism.
  181.         <16>     8/30/94    TÇ        #1183567 StdTypIO routine implementation.
  182.                                     Added Get/SetProp for time_t, ODPoint,
  183.                                     ODRect, Strong/WeakStorageUnitRefs.  Use
  184.                                     Get/SetProp routines for
  185.                                     Strong/WeakStorageUnitRefs.
  186.         <15>     8/29/94    TÇ        #1183567 StdTypIO routine implementation &
  187.                                     fixup
  188.         <14>     8/26/94    VL        1183174: Implemented CloneInto & removed
  189.                                     CloneTo.
  190.         <13>     8/19/94    TÇ        #1180922 Need to Stop using obsolete types
  191.                                     (kOD ID) and fixed a nasty bug where
  192.                                     destPartId was not being initialized to 0
  193.                                     in CloneTo which was causing a crash in
  194.                                     Bento.
  195.         <12>     8/18/94    jpa        Filled in imaging factories [1180387]
  196.         <11>     8/16/94    TÇ        #1180922  Remove more obsolete types from
  197.                                     StdTypes.idl.  Localized kODPartInfo to
  198.                                     this file.
  199.         <10>     8/16/94    VL        1143605: Fixed parameters to CloneInto.
  200.          <9>     8/15/94    JBS        1180387: added Imaging factory methods
  201.          <8>     8/12/94    JBS        1179920: move fWindow from Facet to Frame
  202.          <7>     8/11/94    VL        1180299: Use modified CreateView.
  203.          <6>     8/10/94    JBS        1179919: coordinate system bias changes;
  204.                                     1179920: Frame::AcquireWindow()
  205.          <5>      8/5/94    JBS        #1179151 Part API cleanup
  206.          <4>     7/15/94    TÇ        #ifdef'd out externalization of viewtype &
  207.                                     presentation for now to get the Externalize
  208.                                     method to not crash.
  209.          <3>      7/7/94    JBS        added ::ReleaseAll()
  210.          <2>     6/30/94    jpa        Include Draft.xh, not CMDraft.h.
  211.          <1>     6/30/94    JBS        first checked in
  212.          <0>     6/29/94    SV        SOMverted
  213.     In Progress:
  214.         
  215. */
  216.  
  217. #define ODFrame_Class_Source
  218.  
  219. #ifndef _ALTPOINT_
  220. #include <AltPoint.h>
  221. #endif
  222.  
  223. #ifndef SOM_ODFrame_xih
  224. #define VARIABLE_MACROS
  225. #include <Frame.xih>
  226. #endif
  227.  
  228. #ifndef _PLFMDEF_
  229. #include "PlfmDef.h"
  230. #endif
  231.  
  232. #ifndef SOM_ODFrameFacetIterator_xh
  233. #include <FrFaItr.xh>
  234. #endif
  235.  
  236. #ifndef SOM_ODFacet_xh
  237. #include <Facet.xh>
  238. #endif
  239.  
  240. #ifndef SOM_ODPart_xh
  241. #include <Part.xh>
  242. #endif
  243.  
  244. #ifndef SOM_ODSession_xh
  245. #include <ODSessn.xh>
  246. #endif
  247.  
  248. #ifndef SOM_ODStorageUnit_xh
  249. #include <StorageU.xh>
  250. #endif
  251.  
  252. #ifndef SOM_ODDraft_xh
  253. #include <Draft.xh>
  254. #endif
  255.  
  256. #ifndef SOM_ODDocument_xh
  257. #include <Document.xh>
  258. #endif
  259.  
  260. #ifndef SOM_ODStorageUnitCursor_xh
  261. #include <SUCursor.xh>
  262. #endif
  263.  
  264. #ifndef SOM_ODStorageUnitView_xh
  265. #include <SUView.xh>
  266. #endif
  267.  
  268. #ifndef SOM_ODCanvas_xh
  269. #include <Canvas.xh>
  270. #endif
  271.  
  272. #ifndef SOM_ODShape_xh
  273. #include <Shape.xh>
  274. #endif
  275.  
  276. #ifndef SOM_ODTransform_xh
  277. #include <Trnsform.xh>
  278. #endif
  279.  
  280. #ifndef ODWindowState_Class_Source
  281. #include <WinStat.xh>
  282. #endif
  283.  
  284. #ifndef SOM_ODWindow_xh
  285. #include <Window.xh>
  286. #endif
  287.  
  288. #ifndef SOM_ODWindowIterator_xh
  289. #include <WinIter.xh>
  290. #endif
  291.  
  292. #ifndef SOM_ODArbitrator_xh
  293. #include <Arbitrat.xh>
  294. #endif
  295.  
  296. #ifndef SOM_Module_OpenDoc_Foci_defined
  297. #include <Foci.xh>
  298. #endif
  299.  
  300. #ifndef _ISOSTR_
  301. #include "ISOStr.h"
  302. #endif
  303.  
  304. #ifndef _ODUTILS_
  305. #include <ODUtils.h>
  306. #endif
  307.  
  308. #ifndef _DOCUTILS_
  309. #include <DocUtils.h>
  310. #endif
  311.  
  312. #ifndef SOM_Module_OpenDoc_StdProps_defined
  313. #include <StdProps.xh>
  314. #endif
  315.  
  316. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  317. #include <StdTypes.xh>
  318. #endif
  319.  
  320. #ifndef _EXCEPT_
  321. #include "Except.h"
  322. #endif
  323.  
  324. #ifndef _ORDCOLL_
  325. #include "OrdColl.h"
  326. #endif
  327.  
  328. #ifndef _ODMEMORY_
  329. #include "ODMemory.h"
  330. #endif
  331.  
  332. #ifndef _ODTYPES_
  333. #include <ODTypes.h>
  334. #endif
  335.  
  336. #ifndef _AEHSHTBL_
  337. #include "AEHshTbl.h"
  338. #endif
  339.  
  340. #ifndef _STORUTIL_
  341. #include <StorUtil.h>
  342. #endif
  343.  
  344. #ifndef _STDTYPIO_
  345. #include <StdTypIO.h>
  346. #endif
  347.  
  348. #ifndef _ODDEBUG_
  349. #include "ODDebug.h"
  350. #endif
  351.  
  352. #ifndef _BIAS_
  353. #include "bias.h"
  354. #endif
  355.  
  356. #ifndef _TEMPOBJ_
  357. #include "TempObj.h"
  358. #endif
  359.  
  360. #ifndef _UTILERRS_
  361. #include "UtilErrs.h"
  362. #endif
  363.  
  364. #pragma segment ODFrame
  365.  
  366. //==============================================================================
  367. // Debugging
  368. //==============================================================================
  369.  
  370. //#undef    ODFrameMethodDebug
  371. //#define ODFrameMethodDebug(c,m) PRINT(">>%s::%s\n",c,m)
  372.  
  373. //==============================================================================
  374. // Constants
  375. //==============================================================================
  376.  
  377.     // dirty mask
  378.     const ODULong kNotDirty                    = 0x0000UL;
  379.     const ODULong kContainingFrameDirty        = 0x0001UL;
  380.     const ODULong kFrameShapeDirty            = 0x0002UL; // incidental
  381.     const ODULong kInternalTransformDirty    = 0x0004UL; // incidental
  382.     const ODULong kPartDirty                = 0x0008UL;
  383.     const ODULong kPartInfoDirty            = 0x0010UL;
  384.     const ODULong kViewTypeDirty            = 0x0020UL;
  385.     const ODULong kPresentationDirty        = 0x0040UL;
  386.     const ODULong kFrameGroupDirty            = 0x0080UL;
  387.     const ODULong kSequenceNumberDirty        = 0x0100UL;
  388.     const ODULong kLinkStatusDirty            = 0x0200UL; // incidental
  389.     const ODULong kFlagsDirty                = 0x0400UL;
  390.     const ODULong kAllDirty                    = 0xFFFFUL;
  391.         
  392.     // properties that are "incidental:
  393.     // kODPropFrameShape, kODPropInternalTransform, kODPropBiasTransform,
  394.     // kODPropIsSubframe, kODPropIsOverlaid, kODPropIsFrozen,
  395.     // kODPropDoesPropagateEvents, kODPropLinkStatus
  396.  
  397.     // "incidental" changes that need not force a draft to be dirty:
  398.     const ODULong kIncidentalDirty = 
  399.         (kFrameShapeDirty | kInternalTransformDirty |
  400.          kLinkStatusDirty | kFlagsDirty);
  401.  
  402.     // valid mask
  403.     const ODUShort kFrameIsValid    = 0x0000U;
  404.     const ODUShort kFrameIsRemoved    = 0x0001U;
  405.     const ODUShort kFrameIsClosed    = 0x0002U;
  406.     const ODUShort kFrameIsInRelease    = 0x0004U;
  407.  
  408.     const ODULong kODStorageUnitRefLen = 4UL;
  409.     
  410.     const short    kNumFoci                = 7;
  411.  
  412. //==============================================================================
  413. // Macros
  414. //==============================================================================
  415.  
  416. #define CHECKVALID(RET) if ( _fValidState == kFrameIsValid ) ; else \
  417.                             { ODSetSOMException(ev, kODErrInvalidFrame); return RET;}
  418.                             
  419. #ifdef VOID
  420. #undef VOID
  421. #endif
  422.  
  423. #define VOID /**/
  424.  
  425.  
  426. //==============================================================================
  427. // Forward decls.
  428. //==============================================================================
  429.  
  430. static ODBoolean FrameIsContained( Environment *ev, ODFrame* self,
  431.         ODFrame* frame );
  432.  
  433. //==============================================================================
  434. // ODFrame
  435. //==============================================================================
  436.  
  437. //------------------------------------------------------------------------------
  438. // ODFrame: GetID
  439. //------------------------------------------------------------------------------
  440.  
  441. SOM_Scope ODID  SOMLINK ODFrameGetID(ODFrame *somSelf, Environment *ev)
  442. {
  443.     ODFrameData *somThis = ODFrameGetData(somSelf);
  444.     ODFrameMethodDebug("ODFrame","GetID");
  445.     
  446.     ODID id = 0;
  447.     
  448.     if ( _fNPID != 0 )
  449.         id = _fNPID;
  450.     else
  451.     {
  452.         SOM_TRY
  453.             id = parent_GetID(somSelf, ev);
  454.         SOM_CATCH_ALL
  455.             id = 0;
  456.         SOM_ENDTRY
  457.     }
  458.     return id;
  459. }
  460.  
  461. //------------------------------------------------------------------------------
  462. // ODFrame: AcquireContainingFrame
  463. //------------------------------------------------------------------------------
  464.  
  465. SOM_Scope ODFrame*  SOMLINK ODFrameAcquireContainingFrame(ODFrame *somSelf, Environment *ev)
  466. {
  467.     ODFrameData *somThis = ODFrameGetData(somSelf);
  468.     ODFrameMethodDebug("ODFrame","AcquireContainingFrame");
  469.  
  470.     CHECKVALID(kODNULL);
  471.     
  472.     ODFrame* contFrame = kODNULL;
  473.     SOM_TRY
  474.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  475.         ODID frameID = 0;
  476.     
  477.         // if there is no containing frame, and this is not a root frame,
  478.         // and this is not a non-persistent frame, we should
  479.         // try to get the containing frame from the storage unit
  480.         if ( !_fContainingFrame && !_fIsRoot && su )
  481.         {
  482.             frameID = ODGetWeakSURefProp(ev, su, kODPropContainingFrame, kODWeakStorageUnitRef);
  483.             if ( frameID )
  484.                 _fContainingFrame = _fDraft->AcquireFrame(ev, frameID);
  485.         }
  486.         contFrame = _fContainingFrame;
  487.         // bump ref count for caller
  488.         ODAcquireObject(ev, _fContainingFrame);
  489.     SOM_CATCH_ALL
  490.         contFrame = kODNULL;
  491.     SOM_ENDTRY
  492.     return contFrame;
  493. }
  494.  
  495. SOM_Scope void  SOMLINK ODFrameSetContainingFrame(ODFrame *somSelf, Environment *ev,
  496.         ODFrame* frame)
  497. {
  498.     ODFrameData *somThis = ODFrameGetData(somSelf);
  499.     ODFrameMethodDebug("ODFrame","SetContainingFrame");
  500.  
  501.     CHECKVALID( VOID );
  502.     
  503.     ODSession* session = kODNULL;
  504.     ODWindowState* winState = kODNULL;
  505.     ODWindowIterator* windows = kODNULL;    ODVolatile(windows);
  506.     ODWindow* win = kODNULL;
  507.     
  508.     SOM_TRY
  509.         // when setting contFrame to NULL, make sure it has no facets
  510.         if ( (frame == kODNULL) && _fFacets && (_fFacets->Count() != 0) )
  511.             THROW(kODErrFrameHasFacets);
  512.     
  513.         ODAcquireObject(ev, frame);
  514.         ODReleaseObject(ev, _fContainingFrame);
  515.         _fContainingFrame = frame;
  516.         _fIsRoot = (frame == kODNULL);
  517.         
  518.         // close any part windows with sourceFrame of this frame or an embedded frame.
  519.         if ( frame == kODNULL )
  520.         {
  521.             TempODPart tempPart = somSelf->AcquirePart(ev);
  522.             session = tempPart->GetStorageUnit(ev)->GetSession(ev);
  523.             winState = session->GetWindowState(ev);
  524.             windows = winState->CreateWindowIterator(ev);
  525.             for ( win = windows->First(ev);
  526.                     windows->IsNotComplete(ev);
  527.                     win = windows->Next(ev) )
  528.             {
  529.                 TempODFrame testFrame = win->AcquireSourceFrame(ev);
  530.                 while ( testFrame != kODNULL )
  531.                 {
  532.                     if ( testFrame == somSelf )
  533.                     {
  534.                         win->Acquire(ev);
  535.                         win->CloseAndRemove(ev);
  536.                         ODReleaseObject(ev, testFrame); // sets to kODNULL
  537.                     }
  538.                     else
  539.                     {
  540.                         ODFrame* spam = testFrame;
  541.                         TempODFrame oldFrame = spam;
  542.                         testFrame = kODNULL; // to avoid double Release if following fails
  543.                         testFrame = oldFrame->AcquireContainingFrame(ev);
  544.                     }
  545.                 }
  546.             }
  547.             ODDeleteObject(windows);
  548.         }
  549.         
  550.         somSelf->SetDirty(ev, kContainingFrameDirty);
  551.     SOM_CATCH_ALL
  552.         ODDeleteObject(windows);
  553.     SOM_ENDTRY
  554. }
  555.  
  556. //------------------------------------------------------------------------------
  557. // ODFrame: AcquireWindow
  558. //------------------------------------------------------------------------------
  559.  
  560. SOM_Scope ODWindow*  SOMLINK ODFrameAcquireWindow(ODFrame *somSelf, Environment *ev)
  561. {
  562.     ODFrameData *somThis = ODFrameGetData(somSelf);
  563.     ODFrameMethodDebug("ODFrame","AcquireWindow");
  564.  
  565.     CHECKVALID(kODNULL);
  566. //    WASSERT( !_fIsInLimbo );
  567.     
  568.     ODWindow* window = kODNULL;    ODVolatile(window);
  569.  
  570.     SOM_TRY
  571.         if ( _fWindow )
  572.         {
  573.             window = _fWindow;
  574.             ODAcquireObject(ev, _fWindow);
  575.         }
  576.         else if ( !_fIsRoot )
  577.         {
  578.             TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  579.             window = containingFrame->AcquireWindow(ev); // bumps ref count for caller
  580.         }
  581.     SOM_CATCH_ALL
  582.         window = kODNULL;
  583.     SOM_ENDTRY
  584.     return window;
  585. }
  586.  
  587. SOM_Scope void  SOMLINK ODFrameSetWindow(ODFrame *somSelf, Environment *ev,
  588.         ODWindow* window)
  589. {
  590.     ODFrameData *somThis = ODFrameGetData(somSelf);
  591.     ODFrameMethodDebug("ODFrame","SetWindow");
  592.  
  593.     CHECKVALID( VOID );
  594.  
  595.     SOM_TRY
  596.         if ( !_fIsRoot )
  597.             THROW(kODErrNotRootFrame);
  598.     
  599.         ODAcquireObject(ev, window);
  600.         ODReleaseObject(ev, _fWindow);
  601.         _fWindow = window;
  602.     SOM_CATCH_ALL
  603.     SOM_ENDTRY
  604. }
  605.  
  606. //------------------------------------------------------------------------------
  607. // ODFrame: GetPartInfo
  608. //------------------------------------------------------------------------------
  609.  
  610. SOM_Scope ODInfoType  SOMLINK ODFrameGetPartInfo(ODFrame *somSelf, Environment *ev)
  611. {
  612.     ODFrameData *somThis = ODFrameGetData(somSelf);
  613.     ODFrameMethodDebug("ODFrame","GetPartInfo");
  614.  
  615.     CHECKVALID(kODNULL);
  616.     
  617.     if ( _fPart == kODNULL )    // part has not been internalized yet
  618.     {
  619.         SOM_TRY
  620.             somSelf->AcquirePart(ev)->Release(ev);    // force internalization of partInfo
  621.         SOM_CATCH_ALL
  622.         SOM_ENDTRY
  623.     }
  624.  
  625.     return _fPartInfo;
  626. }
  627.  
  628. SOM_Scope void  SOMLINK ODFrameSetPartInfo(ODFrame *somSelf, Environment *ev,
  629.         ODInfoType partInfo)
  630. {
  631.     ODFrameData *somThis = ODFrameGetData(somSelf);
  632.     ODFrameMethodDebug("ODFrame","SetPartInfo");
  633.  
  634.     CHECKVALID( VOID );
  635.  
  636.     _fPartInfo = partInfo;
  637. }
  638.     
  639. //------------------------------------------------------------------------------
  640. // ODFrame: GetViewType
  641. //------------------------------------------------------------------------------
  642.  
  643. SOM_Scope ODTypeToken  SOMLINK ODFrameGetViewType(ODFrame *somSelf, Environment *ev)
  644. {
  645.     ODFrameData *somThis = ODFrameGetData(somSelf);
  646.     ODFrameMethodDebug("ODFrame","GetViewType");
  647.  
  648.     CHECKVALID(kODNULL);
  649.     
  650.     return _fViewType;
  651. }
  652.  
  653. SOM_Scope void  SOMLINK ODFrameSetViewType(ODFrame *somSelf, Environment *ev,
  654.         ODTypeToken viewType)
  655. {
  656.     ODFrameData *somThis = ODFrameGetData(somSelf);
  657.     ODFrameMethodDebug("ODFrame","SetViewType");
  658.  
  659.     CHECKVALID( VOID );
  660.  
  661.     SOM_TRY
  662.         if ( kODNULL == viewType )
  663.             THROW(kODErrIllegalNullTokenInput);
  664.     
  665.         if ( _fViewType != viewType )
  666.         {
  667.             _fViewType = viewType;
  668.     
  669.             somSelf->SetDirty(ev, kViewTypeDirty);
  670.         }
  671.     SOM_CATCH_ALL
  672.     SOM_ENDTRY
  673. }
  674.  
  675. SOM_Scope void  SOMLINK ODFrameChangeViewType(ODFrame *somSelf, Environment *ev,
  676.         ODTypeToken viewType)
  677. {
  678.     ODFrameData *somThis = ODFrameGetData(somSelf);
  679.     ODFrameMethodDebug("ODFrame","ChangeViewType");
  680.  
  681.     CHECKVALID( VOID );
  682.  
  683.     SOM_TRY
  684.         if ( kODNULL == viewType )
  685.             THROW(kODErrIllegalNullTokenInput);
  686.     
  687.         if ( viewType != _fViewType )
  688.         {
  689.             _fViewType = viewType;
  690.             
  691.             TempODPart tempPart = somSelf->AcquirePart(ev);
  692.             tempPart->ViewTypeChanged(ev, somSelf);
  693.         
  694.             somSelf->SetDirty(ev, kViewTypeDirty);
  695.         }
  696.     SOM_CATCH_ALL
  697.     SOM_ENDTRY
  698. }
  699.  
  700. //------------------------------------------------------------------------------
  701. // ODFrame: GetPresentation
  702. //------------------------------------------------------------------------------
  703.  
  704. SOM_Scope ODTypeToken  SOMLINK ODFrameGetPresentation(ODFrame *somSelf, Environment *ev)
  705. {
  706.     ODFrameData *somThis = ODFrameGetData(somSelf);
  707.     ODFrameMethodDebug("ODFrame","GetPresentation");
  708.  
  709.     CHECKVALID(kODNULL);
  710.     
  711.     return _fPresentation;
  712. }
  713.  
  714. SOM_Scope void  SOMLINK ODFrameSetPresentation(ODFrame *somSelf, Environment *ev,
  715.         ODTypeToken presentation)
  716. {
  717.     ODFrameData *somThis = ODFrameGetData(somSelf);
  718.     ODFrameMethodDebug("ODFrame","SetPresentation");
  719.  
  720.     CHECKVALID( VOID );
  721.     
  722.     SOM_TRY
  723.         if ( kODNULL == presentation )
  724.             THROW(kODErrIllegalNullTokenInput);
  725.     
  726.         if ( _fPresentation != presentation )
  727.         {
  728.             _fPresentation = presentation;
  729.         
  730.             somSelf->SetDirty(ev, kPresentationDirty);
  731.         }
  732.     SOM_CATCH_ALL
  733.     SOM_ENDTRY
  734. }
  735.  
  736. SOM_Scope void  SOMLINK ODFrameChangePresentation(ODFrame *somSelf, Environment *ev,
  737.         ODTypeToken presentation)
  738. {
  739.     ODFrameData *somThis = ODFrameGetData(somSelf);
  740.     ODFrameMethodDebug("ODFrame","ChangePresentation");
  741.  
  742.     CHECKVALID( VOID );
  743.     
  744.     SOM_TRY
  745.         if ( kODNULL == presentation )
  746.             THROW(kODErrIllegalNullTokenInput);
  747.     
  748.         if ( _fPresentation != presentation )
  749.         {
  750.             _fPresentation = presentation;
  751.  
  752.             TempODPart tempPart = somSelf->AcquirePart(ev);
  753.             tempPart->PresentationChanged(ev, somSelf);
  754.         
  755.             somSelf->SetDirty(ev, kPresentationDirty);
  756.         }
  757.     SOM_CATCH_ALL
  758.     SOM_ENDTRY
  759. }
  760.  
  761. //------------------------------------------------------------------------------
  762. // ODFrame: GetFrameGroup
  763. //------------------------------------------------------------------------------
  764.  
  765. SOM_Scope ODULong  SOMLINK ODFrameGetFrameGroup(ODFrame *somSelf, Environment *ev)
  766. {
  767.     ODFrameData *somThis = ODFrameGetData(somSelf);
  768.     ODFrameMethodDebug("ODFrame","GetFrameGroup");
  769.  
  770.     CHECKVALID(0);
  771.     
  772.     return _fFrameGroup;
  773. }
  774.  
  775. SOM_Scope void  SOMLINK ODFrameSetFrameGroup(ODFrame *somSelf, Environment *ev,
  776.         ODULong groupID)
  777. {
  778.     ODFrameData *somThis = ODFrameGetData(somSelf);
  779.     ODFrameMethodDebug("ODFrame","SetFrameGroup");
  780.  
  781.     CHECKVALID( VOID );
  782.     
  783.     SOM_TRY
  784.         if ( groupID != _fFrameGroup )
  785.         {
  786.             _fFrameGroup = groupID;
  787.         
  788.             somSelf->SetDirty(ev, kFrameGroupDirty);
  789.         }
  790.     SOM_CATCH_ALL
  791.     SOM_ENDTRY
  792. }
  793.  
  794. //------------------------------------------------------------------------------
  795. // ODFrame: GetSequenceNumber
  796. //------------------------------------------------------------------------------
  797.  
  798. SOM_Scope ODULong  SOMLINK ODFrameGetSequenceNumber(ODFrame *somSelf, Environment *ev)
  799. {
  800.     ODFrameData *somThis = ODFrameGetData(somSelf);
  801.     ODFrameMethodDebug("ODFrame","GetSequenceNumber");
  802.  
  803.     CHECKVALID(0);
  804.     
  805.     return _fSequenceNumber;
  806. }
  807.  
  808. SOM_Scope void  SOMLINK ODFrameChangeSequenceNumber(ODFrame *somSelf, Environment *ev,
  809.         ODULong sequenceNumber)
  810. {
  811.     ODFrameData *somThis = ODFrameGetData(somSelf);
  812.     ODFrameMethodDebug("ODFrame","ChangeSequenceNumber");
  813.  
  814.     CHECKVALID( VOID );
  815.     
  816.     SOM_TRY
  817.         if ( sequenceNumber != _fSequenceNumber )
  818.         {
  819.             _fSequenceNumber = sequenceNumber;
  820.         
  821.             somSelf->SetDirty(ev, kSequenceNumberDirty);
  822.         }
  823.     SOM_CATCH_ALL
  824.     SOM_ENDTRY
  825. }
  826.  
  827. //------------------------------------------------------------------------------
  828. // ODFrame: IsRoot
  829. //------------------------------------------------------------------------------
  830.  
  831. SOM_Scope ODBoolean  SOMLINK ODFrameIsRoot(ODFrame *somSelf, Environment *ev)
  832. {
  833.     ODFrameData *somThis = ODFrameGetData(somSelf);
  834.     ODFrameMethodDebug("ODFrame","IsRoot");
  835.  
  836.     CHECKVALID(kODFalse);
  837.     
  838.     return _fIsRoot;
  839. }
  840.  
  841. //------------------------------------------------------------------------------
  842. // ODFrame: IsSubframe
  843. //------------------------------------------------------------------------------
  844.  
  845. SOM_Scope ODBoolean  SOMLINK ODFrameIsSubframe(ODFrame *somSelf, Environment *ev)
  846. {
  847.     ODFrameData *somThis = ODFrameGetData(somSelf);
  848.     ODFrameMethodDebug("ODFrame","IsSubframe");
  849.  
  850.     CHECKVALID(kODFalse);
  851.     
  852.     return _fIsSubframe;
  853. }
  854.  
  855. SOM_Scope void  SOMLINK ODFrameSetSubframe(ODFrame *somSelf, Environment *ev,
  856.         ODBoolean isSubframe)
  857. {
  858.     ODFrameData *somThis = ODFrameGetData(somSelf);
  859.     ODFrameMethodDebug("ODFrame","SetSubframe");
  860.  
  861.     CHECKVALID( VOID );
  862.     
  863.     SOM_TRY
  864.         if ( isSubframe != _fIsSubframe)
  865.         {
  866.             _fIsSubframe = isSubframe;
  867.         
  868.             somSelf->SetDirty(ev, kFlagsDirty);
  869.         }
  870.     SOM_CATCH_ALL
  871.     SOM_ENDTRY
  872. }
  873.     
  874. //------------------------------------------------------------------------------
  875. // ODFrame: IsOverlaid
  876. //------------------------------------------------------------------------------
  877.  
  878. SOM_Scope ODBoolean  SOMLINK ODFrameIsOverlaid(ODFrame *somSelf, Environment *ev)
  879. {
  880.     ODFrameData *somThis = ODFrameGetData(somSelf);
  881.     ODFrameMethodDebug("ODFrame","IsOverlaid");
  882.  
  883.     CHECKVALID(kODFalse);
  884.     
  885.     return _fIsOverlaid;
  886. }
  887.  
  888. //------------------------------------------------------------------------------
  889. // ODFrame: IsFrozen
  890. //------------------------------------------------------------------------------
  891.  
  892. SOM_Scope ODBoolean  SOMLINK ODFrameIsFrozen(ODFrame *somSelf, Environment *ev)
  893. {
  894.     ODFrameData *somThis = ODFrameGetData(somSelf);
  895.     ODFrameMethodDebug("ODFrame","IsFrozen");
  896.  
  897.     CHECKVALID(kODFalse);
  898.     
  899.     return _fIsFrozen;
  900. }
  901.  
  902. SOM_Scope void  SOMLINK ODFrameSetFrozen(ODFrame *somSelf, Environment *ev,
  903.         ODBoolean isFrozen)
  904. {
  905.     ODFrameData *somThis = ODFrameGetData(somSelf);
  906.     ODFrameMethodDebug("ODFrame","SetFrozen");
  907.  
  908.     CHECKVALID( VOID );
  909.     
  910.     SOM_TRY
  911.         if ( isFrozen != _fIsFrozen)
  912.         {
  913.             _fIsFrozen = isFrozen;
  914.         
  915.             somSelf->SetDirty(ev, kFlagsDirty);
  916.         }
  917.     SOM_CATCH_ALL
  918.     SOM_ENDTRY
  919. }
  920.  
  921. //------------------------------------------------------------------------------
  922. // ODFrame: DoesPropagateEvents
  923. //------------------------------------------------------------------------------
  924.  
  925. SOM_Scope ODBoolean  SOMLINK ODFrameDoesPropagateEvents(ODFrame *somSelf, Environment *ev)
  926. {
  927.     ODFrameData *somThis = ODFrameGetData(somSelf);
  928.     ODFrameMethodDebug("ODFrame","DoesPropagateEvents");
  929.  
  930.     CHECKVALID(kODFalse);
  931.     
  932.     return _fDoesPropagateEvents;
  933. }
  934.  
  935. SOM_Scope void  SOMLINK ODFrameSetPropagateEvents(ODFrame *somSelf, Environment *ev,
  936.         ODBoolean doesPropagateEvents)
  937. {
  938.     ODFrameData *somThis = ODFrameGetData(somSelf);
  939.     ODFrameMethodDebug("ODFrame","SetPropagateEvents");
  940.  
  941.     CHECKVALID( VOID );
  942.     
  943.     if ( doesPropagateEvents != _fDoesPropagateEvents)
  944.         _fDoesPropagateEvents = doesPropagateEvents;
  945. }
  946.     
  947. //------------------------------------------------------------------------------
  948. // ODFrame: IsInLimbo
  949. //------------------------------------------------------------------------------
  950.  
  951. SOM_Scope ODBoolean  SOMLINK ODFrameIsInLimbo(ODFrame *somSelf, Environment *ev)
  952. {
  953.     ODFrameData *somThis = ODFrameGetData(somSelf);
  954.     ODFrameMethodDebug("ODFrame","IsInLimbo");
  955.  
  956.     CHECKVALID(kODFalse);
  957.     
  958.     return _fIsInLimbo;
  959. }
  960.  
  961. SOM_Scope void  SOMLINK ODFrameSetInLimbo(ODFrame *somSelf, Environment *ev,
  962.         ODBoolean isInLimbo)
  963. {
  964.     ODFrameData *somThis = ODFrameGetData(somSelf);
  965.     ODFrameMethodDebug("ODFrame","SetInLimbo");
  966.  
  967.     CHECKVALID( VOID );
  968.     
  969. //    if ( isInLimbo != _fIsInLimbo)
  970.     _fIsInLimbo = isInLimbo;
  971.     if ( isInLimbo )
  972.     {
  973.         SOM_TRY
  974.             // Since SetInLimbo is called only on the root frame of a hierarchy
  975.             // being put into limbo, we need to search through all embedded
  976.             // frames for any with foci and then release them.  To make this
  977.             // less expensive, we'll first build a list of frame/focus pairs,
  978.             // then for each frame found do a recursive search to see if it is
  979.             // contained within (or equal to) this frame.
  980.             
  981.             TempODPart tempPart = somSelf->AcquirePart(ev);
  982.             ODSession* session = tempPart->GetStorageUnit(ev)->GetSession(ev);
  983.             ODArbitrator* arb = session->GetArbitrator(ev);
  984.  
  985.             ODFocusType foci[kNumFoci] = { kODSelectionFocus, kODMenuFocus, kODKeyFocus,
  986.                     kODModalFocus, kODMouseFocus, kODScrollingFocus, kODClipboardFocus };
  987.             ODFocusType* focus = foci;
  988.             for ( int i = 0; i < kNumFoci; ++i )
  989.             {
  990.                 ODTypeToken focusToken = session->Tokenize( ev, *focus++ );
  991.                 TempODFrame activeFrame = session->GetArbitrator(ev)->
  992.                         AcquireFocusOwner( ev, focusToken );
  993.                 if ( FrameIsContained( ev, somSelf, activeFrame ) )
  994.                     arb->TransferFocus( ev, focusToken, kODNULL, kODNULL );
  995.             }
  996.         SOM_CATCH_ALL
  997.         SOM_ENDTRY
  998.     }
  999. }
  1000.     
  1001. //------------------------------------------------------------------------------
  1002. // ODFrame: AcquirePart
  1003. //------------------------------------------------------------------------------
  1004.  
  1005. SOM_Scope ODPart*  SOMLINK ODFrameAcquirePart(ODFrame *somSelf, Environment *ev)
  1006. {
  1007.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1008.     ODFrameMethodDebug("ODFrame","AcquirePart");
  1009.  
  1010.     CHECKVALID(kODNULL);
  1011.     
  1012.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1013.     
  1014.     SOM_TRY
  1015.         if ( _fPart == kODNULL )    // part has not been internalized yet
  1016.         {
  1017.             ODStorageUnit     *su = somSelf->GetStorageUnit(ev);
  1018.             ODStorageUnitView *suView = kODNULL;
  1019.             
  1020.             if ( su )
  1021.             {
  1022.                 _fPart = _fDraft->AcquirePart(ev,
  1023.                         ODGetStrongSURefProp(ev, su, kODPropPart, kODStrongStorageUnitRef));
  1024.                 ASSERT(_fPart, kODErrAssertionFailed);
  1025.                 
  1026.                 su->Focus(ev, kODPropPartInfo, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  1027.                 {    
  1028.                     TempODStorageUnitView suView = su->CreateView(ev);
  1029.                     _fPartInfo = (ODInfoType)(_fPart->ReadPartInfo(ev, somSelf, suView));
  1030.                 }
  1031.                 
  1032.                 _fPart->DisplayFrameConnected(ev, somSelf);
  1033.  
  1034.                 i = somSelf->CreateFacetIterator(ev);
  1035.                 for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1036.                     _fPart->FacetAdded(ev, facet);
  1037.                 ODDeleteObject(i);
  1038.             }
  1039.         }
  1040.         // bump ref count for caller
  1041.         ODAcquireObject(ev, _fPart);
  1042.     SOM_CATCH_ALL
  1043.         ODSafeReleaseObject(_fPart); _fPart = kODNULL;
  1044.         ODDeleteObject(i);
  1045.     SOM_ENDTRY
  1046.     
  1047.     return _fPart;
  1048. }
  1049.     
  1050. //------------------------------------------------------------------------------
  1051. // ODFrame: ChangePart
  1052. //------------------------------------------------------------------------------
  1053.  
  1054. SOM_Scope void  SOMLINK ODFrameChangePart(ODFrame *somSelf, Environment *ev,
  1055.         ODPart* part)
  1056. {
  1057.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1058.     ODFrameMethodDebug("ODFrame","ChangePart");
  1059.  
  1060.     CHECKVALID( VOID );
  1061.     
  1062.     WASSERT_IS_PART_WRAPPER( ev, part );
  1063.  
  1064.     SOM_TRY
  1065.         if ( !part )
  1066.             THROW(kODErrIllegalNullPartInput);
  1067.         if ( _fPart == kODNULL )
  1068.             somSelf->AcquirePart(ev)->Release(ev);    // force internalization of part
  1069.         ASSERT( _fPart, kODErrInvalidPersistentFormat);
  1070.         
  1071.         ODFrameFacetIterator* i = somSelf->CreateFacetIterator(ev);
  1072.         ODFacet* facet = kODNULL;
  1073.         
  1074.         for (facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1075.             _fPart->FacetRemoved(ev, facet);
  1076.         TRY
  1077.             _fPart->DisplayFrameRemoved(ev, somSelf);
  1078.         CATCH_ALL
  1079.             WARN("Part returned err %d removing frame",ErrorCode());
  1080.             // don't reraise
  1081.         ENDTRY
  1082.     
  1083.         ODAcquireObject(ev, part);
  1084.         ODReleaseObject(ev, _fPart);
  1085.         _fPart = part;
  1086.     
  1087.         _fPart->DisplayFrameAdded(ev, somSelf);
  1088.         for (facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1089.             _fPart->FacetAdded(ev, facet);
  1090.         
  1091.         delete i;
  1092.     
  1093.         somSelf->SetDirty(ev, kPartDirty);
  1094.     SOM_CATCH_ALL
  1095.     SOM_ENDTRY
  1096. }
  1097.     
  1098. //------------------------------------------------------------------------------
  1099. // ODFrame: FacetAdded
  1100. //------------------------------------------------------------------------------
  1101.  
  1102. SOM_Scope void  SOMLINK ODFrameFacetAdded(ODFrame *somSelf, Environment *ev,
  1103.         ODFacet* facet)
  1104. {
  1105.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1106.     ODFrameMethodDebug("ODFrame","FacetAdded");
  1107.  
  1108.     CHECKVALID( VOID );
  1109.     
  1110.     SOM_TRY
  1111.         TempODPart tempPart = somSelf->AcquirePart(ev);
  1112.         _fFacets->AddLast(facet);
  1113.         tempPart->FacetAdded(ev, facet);
  1114.     SOM_CATCH_ALL
  1115.     SOM_ENDTRY
  1116. }
  1117.  
  1118. //------------------------------------------------------------------------------
  1119. // ODFrame: FacetRemoved
  1120. //------------------------------------------------------------------------------
  1121.  
  1122. SOM_Scope void  SOMLINK ODFrameFacetRemoved(ODFrame *somSelf, Environment *ev,
  1123.         ODFacet* facet)
  1124. {
  1125.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1126.     ODFrameMethodDebug("ODFrame","FacetRemoved");
  1127.  
  1128.     CHECKVALID( VOID );
  1129.     
  1130.     SOM_TRY
  1131.         if ( _fFacets->Contains(facet) )
  1132.         {
  1133.             _fFacets->Remove(facet);
  1134.             TempODPart tempPart = somSelf->AcquirePart(ev);
  1135.             tempPart->FacetRemoved(ev, facet);
  1136.         }
  1137.     SOM_CATCH_ALL
  1138.     SOM_ENDTRY
  1139. }
  1140.  
  1141. //------------------------------------------------------------------------------
  1142. // ODFrame: CreateFacetIterator
  1143. //------------------------------------------------------------------------------
  1144.  
  1145. SOM_Scope ODFrameFacetIterator*  SOMLINK ODFrameCreateFacetIterator(ODFrame *somSelf, Environment *ev)
  1146. {
  1147.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1148.     ODFrameMethodDebug("ODFrame","CreateFacetIterator");
  1149.  
  1150.     ODFrameFacetIterator* iter = kODNULL; ODVolatile(iter);
  1151.  
  1152.     CHECKVALID(kODNULL);
  1153.     
  1154.     SOM_TRY
  1155.         iter = new ODFrameFacetIterator;
  1156.           THROW_IF_NULL(iter);
  1157.         iter->InitFrameFacetIterator(ev, somSelf);
  1158.     SOM_CATCH_ALL
  1159.         ODDeleteObject(iter);
  1160.         iter = kODNULL;
  1161.     SOM_ENDTRY
  1162.     return iter;
  1163. }
  1164.  
  1165. //------------------------------------------------------------------------------
  1166. // ODFrame: CreateShape
  1167. //------------------------------------------------------------------------------
  1168.  
  1169. SOM_Scope ODShape*  SOMLINK ODFrameCreateShape(ODFrame *somSelf, Environment *ev)
  1170. {
  1171.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1172.     ODFrameMethodDebug("ODFrame","CreateShape");
  1173.  
  1174.     CHECKVALID(kODNULL);
  1175.     
  1176.     ODShape *s = kODNULL;  ODVolatile(s);
  1177.     
  1178.     SOM_TRY
  1179.         s = new ODShape;
  1180.         THROW_IF_NULL(s);
  1181.         s->InitShape(ev);
  1182.     SOM_CATCH_ALL
  1183.           ODDeleteObject(s);
  1184.         s = kODNULL;
  1185.     SOM_ENDTRY
  1186.     return s;
  1187. }
  1188.  
  1189. //------------------------------------------------------------------------------
  1190. // ODFrame: AcquireFrameShape
  1191. //------------------------------------------------------------------------------
  1192.  
  1193. SOM_Scope ODShape*  SOMLINK ODFrameAcquireFrameShape(ODFrame *somSelf, Environment *ev,
  1194.         ODCanvas* biasCanvas)
  1195. {
  1196.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1197.     ODFrameMethodDebug("ODFrame","AcquireFrameShape");
  1198.  
  1199.     CHECKVALID(kODNULL);
  1200.     
  1201.     ODShape* s;
  1202.     SOM_TRY
  1203.         s = BiasShapeGet(ev, _fFrameShape, biasCanvas);
  1204.     SOM_CATCH_ALL
  1205.         s = kODNULL;
  1206.     SOM_ENDTRY
  1207.     return s;
  1208. }
  1209.  
  1210. //------------------------------------------------------------------------------
  1211. // ODFrame: ChangeFrameShape
  1212. //------------------------------------------------------------------------------
  1213.  
  1214. SOM_Scope void  SOMLINK ODFrameChangeFrameShape(ODFrame *somSelf, Environment *ev,
  1215.         ODShape* shape, ODCanvas* biasCanvas)
  1216. {
  1217.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1218.     ODFrameMethodDebug("ODFrame","ChangeFrameShape");
  1219.  
  1220.     CHECKVALID( VOID );
  1221.     
  1222.     ODSession* session;
  1223.     ODTypeToken    selectionFocus;
  1224.  
  1225.     SOM_TRY
  1226.         if (shape)
  1227.         {
  1228.             TempODPart tempPart = somSelf->AcquirePart(ev);
  1229.             session = tempPart->GetStorageUnit(ev)->GetSession(ev);
  1230.             selectionFocus = session->Tokenize(ev, kODSelectionFocus);
  1231.     
  1232.             TempODFrame activeFrame = session->GetArbitrator(ev)->AcquireFocusOwner(ev, selectionFocus);
  1233.             if ( ODObjectsAreEqual(ev, somSelf, activeFrame) )
  1234.                 somSelf->InvalidateActiveBorder(ev);
  1235.     
  1236.             ODAcquireObject(ev, shape);
  1237.             ODReleaseObject(ev, _fFrameShape);
  1238.             _fFrameShape = BiasShapeSet(ev, shape, biasCanvas);
  1239.     
  1240.             tempPart->FrameShapeChanged(ev, somSelf);
  1241.         }
  1242.         else
  1243.             THROW(kODErrIllegalNullShapeInput);    // frame's MUST have a frameShape
  1244.     
  1245.         somSelf->SetDirty(ev, kFrameShapeDirty);
  1246.     SOM_CATCH_ALL
  1247.     SOM_ENDTRY
  1248. }
  1249.  
  1250. //------------------------------------------------------------------------------
  1251. // ODFrame: RequestFrameShape
  1252. //------------------------------------------------------------------------------
  1253.  
  1254. SOM_Scope ODShape*  SOMLINK ODFrameRequestFrameShape(ODFrame *somSelf, Environment *ev,
  1255.         ODShape* shape, ODCanvas* biasCanvas)
  1256. {
  1257.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1258.     ODFrameMethodDebug("ODFrame","RequestFrameShape");
  1259.  
  1260.     CHECKVALID(kODNULL);
  1261.     
  1262.     ODShape* s = kODNULL;
  1263.     SOM_TRY
  1264.         TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1265.         ODSession* session;
  1266.         ODTypeToken    selectionFocus;
  1267.         
  1268.         if ( shape == kODNULL )
  1269.         {
  1270.             THROW(kODErrIllegalNullShapeInput);
  1271.             return kODNULL;
  1272.         }
  1273.     
  1274.         if ( containingFrame )    // root frames can't negotiate
  1275.         {
  1276.             TempODPart containingPart = containingFrame->AcquirePart(ev);
  1277.             BiasShapeSet(ev, shape, biasCanvas);
  1278.             if (containingPart)
  1279.                 shape = containingPart->RequestFrameShape(ev, somSelf, shape);    
  1280.  
  1281.             TempODPart tempPart = somSelf->AcquirePart(ev);
  1282.             session = tempPart->GetStorageUnit(ev)->GetSession(ev);
  1283.             selectionFocus = session->Tokenize(ev, kODSelectionFocus);
  1284.     
  1285.             TempODFrame activeFrame = session->GetArbitrator(ev)->AcquireFocusOwner(ev, selectionFocus);
  1286.             if ( ODObjectsAreEqual(ev, somSelf, activeFrame) )
  1287.                 somSelf->InvalidateActiveBorder(ev);
  1288.     
  1289.             // shape's refcount is already inflated by containing part
  1290.             ODReleaseObject(ev, _fFrameShape);
  1291.             _fFrameShape = shape;
  1292.         }
  1293.     
  1294.         somSelf->SetDirty(ev, kFrameShapeDirty);
  1295.     
  1296.         s = BiasShapeGet(ev, _fFrameShape, biasCanvas);
  1297.     SOM_CATCH_ALL
  1298.         s = kODNULL;
  1299.     SOM_ENDTRY
  1300.     return s;
  1301. }
  1302.  
  1303. //------------------------------------------------------------------------------
  1304. // ODFrame: AcquireUsedShape
  1305. //------------------------------------------------------------------------------
  1306.  
  1307. SOM_Scope ODShape*  SOMLINK ODFrameAcquireUsedShape(ODFrame *somSelf, Environment *ev,
  1308.         ODCanvas* biasCanvas)
  1309. {
  1310.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1311.     ODFrameMethodDebug("ODFrame","AcquireUsedShape");
  1312.  
  1313.     CHECKVALID(kODNULL);
  1314.     
  1315.     ODShape* s;
  1316.     SOM_TRY
  1317.         if ( _fUsedShape )
  1318.             s = BiasShapeGet(ev, _fUsedShape, biasCanvas);
  1319.         else
  1320.             s = ODCopyAndRelease(ev, BiasShapeGet(ev, _fFrameShape, biasCanvas));
  1321.     SOM_CATCH_ALL
  1322.         s = kODNULL;
  1323.     SOM_ENDTRY
  1324.     return s;
  1325. }
  1326.  
  1327. //------------------------------------------------------------------------------
  1328. // ODFrame: ChangeUsedShape
  1329. //------------------------------------------------------------------------------
  1330.  
  1331. SOM_Scope void  SOMLINK ODFrameChangeUsedShape(ODFrame *somSelf, Environment *ev,
  1332.         ODShape* shape, ODCanvas* biasCanvas)
  1333. {
  1334.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1335.     ODFrameMethodDebug("ODFrame","ChangeUsedShape");
  1336.  
  1337.     CHECKVALID( VOID );
  1338.     
  1339.     SOM_TRY
  1340.         TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1341.         TempODPart containingPart = kODNULL;
  1342.         
  1343.         ODAcquireObject(ev, shape);
  1344.         ODReleaseObject(ev, _fUsedShape);
  1345.         _fUsedShape = BiasShapeSet(ev, shape, biasCanvas);
  1346.     
  1347.         if ( containingFrame )
  1348.         {    containingPart = containingFrame->AcquirePart(ev);
  1349.             if ( containingPart )
  1350.                 containingPart->UsedShapeChanged(ev, somSelf);
  1351.         }
  1352.     SOM_CATCH_ALL
  1353.     SOM_ENDTRY
  1354. }
  1355.  
  1356. //------------------------------------------------------------------------------
  1357. // ODFrame: CreateTransform
  1358. //------------------------------------------------------------------------------
  1359.  
  1360. SOM_Scope ODTransform*  SOMLINK ODFrameCreateTransform(ODFrame *somSelf, Environment *ev)
  1361. {
  1362.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1363.     ODFrameMethodDebug("ODFrame","CreateTransform");
  1364.  
  1365.     CHECKVALID(kODNULL);
  1366.     
  1367.     ODTransform *t = kODNULL;  ODVolatile(t);
  1368.     SOM_TRY
  1369.         t = new ODTransform;
  1370.         THROW_IF_NULL(t);
  1371.         t->InitTransform(ev);
  1372.     SOM_CATCH_ALL
  1373.         ODDeleteObject(t);
  1374.         t = kODNULL;
  1375.     SOM_ENDTRY
  1376.     return t;
  1377. }
  1378.  
  1379. //------------------------------------------------------------------------------
  1380. // ODFrame: AcquireInternalTransform
  1381. //------------------------------------------------------------------------------
  1382.  
  1383. SOM_Scope ODTransform*  SOMLINK ODFrameAcquireInternalTransform(ODFrame *somSelf, Environment *ev,
  1384.         ODCanvas* biasCanvas)
  1385. {
  1386.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1387.     ODFrameMethodDebug("ODFrame","AcquireInternalTransform");
  1388.  
  1389.     CHECKVALID(kODNULL);
  1390.     
  1391.     ODTransform *t;
  1392.     SOM_TRY
  1393.         t = BiasTransformGet(ev, _fInternalTransform, biasCanvas);
  1394.     SOM_CATCH_ALL
  1395.         t = kODNULL;
  1396.     SOM_ENDTRY
  1397.     return t;
  1398. }
  1399.  
  1400. //------------------------------------------------------------------------------
  1401. // ODFrame: ChangeInternalTransform
  1402. //------------------------------------------------------------------------------
  1403.  
  1404. SOM_Scope void  SOMLINK ODFrameChangeInternalTransform(ODFrame *somSelf, Environment *ev,
  1405.         ODTransform* transform, ODCanvas* biasCanvas)
  1406. {
  1407.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1408.     ODFrameMethodDebug("ODFrame","ChangeInternalTransform");
  1409.  
  1410.     CHECKVALID( VOID );
  1411.     
  1412.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1413.     SOM_TRY
  1414.         if ( transform )
  1415.         {
  1416.             ODAcquireObject(ev, transform);
  1417.             ODReleaseObject(ev, _fInternalTransform);
  1418.             _fInternalTransform = BiasTransformSet(ev, transform, biasCanvas);
  1419.             
  1420.             i = somSelf->CreateFacetIterator(ev);
  1421.             for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1422.                 facet->InternalTransformChanged(ev);
  1423.             delete i;
  1424.         }
  1425.         else
  1426.         {
  1427.             THROW(kODErrIllegalNullTransformInput);
  1428.         }
  1429.     
  1430.         somSelf->SetDirty(ev, kInternalTransformDirty);
  1431.     SOM_CATCH_ALL
  1432.         ODDeleteObject(i);
  1433.     SOM_ENDTRY
  1434. }
  1435.  
  1436. //------------------------------------------------------------------------------
  1437. // ODFrame: GetContentExtent
  1438. //------------------------------------------------------------------------------
  1439.  
  1440. SOM_Scope void  SOMLINK ODFrameGetContentExtent(ODFrame *somSelf, Environment *ev, ODPoint* contentExtent)
  1441. {
  1442.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1443.     ODFrameMethodDebug("ODFrame","GetContentExtent");
  1444.  
  1445.     ODPoint pt(0,0);
  1446.     *contentExtent = pt;
  1447.  
  1448.     CHECKVALID(VOID);
  1449.     
  1450.     *contentExtent = _fContentExtent;
  1451. }
  1452.  
  1453. //------------------------------------------------------------------------------
  1454. // ODFrame: ChangeContentExtent
  1455. //------------------------------------------------------------------------------
  1456.  
  1457. SOM_Scope void  SOMLINK ODFrameChangeContentExtent(ODFrame *somSelf, Environment *ev,
  1458.         ODPoint* contentExtent)
  1459. {
  1460.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1461.     ODFrameMethodDebug("ODFrame","ChangeContentExtent");
  1462.  
  1463.     CHECKVALID( VOID );
  1464.     
  1465.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1466.     SOM_TRY
  1467.         _fContentExtent = *contentExtent;
  1468.         
  1469.         // compute biasTransform of each facet's canvas
  1470.         i = somSelf->CreateFacetIterator(ev);    
  1471.         for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1472.         {
  1473.             if ( facet->HasCanvas(ev) )
  1474.                 facet->GetCanvas(ev)->ComputeBiasTransform(ev);
  1475.         }
  1476.         delete i;
  1477.     SOM_CATCH_ALL
  1478.         ODDeleteObject(i);
  1479.     SOM_ENDTRY
  1480. }
  1481.  
  1482. //------------------------------------------------------------------------------
  1483. // ODFrame: IsDroppable
  1484. //------------------------------------------------------------------------------
  1485.  
  1486. SOM_Scope ODBoolean  SOMLINK ODFrameIsDroppable(ODFrame *somSelf, Environment *ev)
  1487. {
  1488.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1489.     ODFrameMethodDebug("ODFrame","IsDroppable");
  1490.  
  1491.     CHECKVALID(kODFalse);
  1492.     
  1493.     return _fIsDroppable;
  1494. }
  1495.  
  1496. SOM_Scope void  SOMLINK ODFrameSetDroppable(ODFrame *somSelf, Environment *ev,
  1497.         ODBoolean isDroppable)
  1498. {
  1499.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1500.     ODFrameMethodDebug("ODFrame","SetDroppable");
  1501.  
  1502.     CHECKVALID( VOID );
  1503.     
  1504.     _fIsDroppable = isDroppable;
  1505. }
  1506.  
  1507. //------------------------------------------------------------------------------
  1508. // ODFrame: IsDragging
  1509. //------------------------------------------------------------------------------
  1510.  
  1511. SOM_Scope ODBoolean  SOMLINK ODFrameIsDragging(ODFrame *somSelf, Environment *ev)
  1512. {
  1513.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1514.     ODFrameMethodDebug("ODFrame","IsDragging");
  1515.  
  1516.     CHECKVALID(kODFalse);
  1517.     
  1518.     return _fIsDragging;
  1519. }
  1520.  
  1521. //------------------------------------------------------------------------------
  1522. // ODFrame: SetDragging
  1523. //------------------------------------------------------------------------------
  1524.  
  1525. SOM_Scope void  SOMLINK ODFrameSetDragging(ODFrame *somSelf, Environment *ev,
  1526.         ODBoolean isDragging)
  1527. {
  1528.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1529.     ODFrameMethodDebug("ODFrame","SetDragging");
  1530.  
  1531.     CHECKVALID( VOID );
  1532.     
  1533.     _fIsDragging = isDragging;
  1534. }
  1535.  
  1536. //------------------------------------------------------------------------------
  1537. // ODFrame: ContentUpdated
  1538. //------------------------------------------------------------------------------
  1539.  
  1540. SOM_Scope void  SOMLINK ODFrameContentUpdated(ODFrame *somSelf, Environment *ev,
  1541.         ODUpdateID change)
  1542. {
  1543.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1544.     ODFrameMethodDebug("ODFrame","ContentUpdated");
  1545.  
  1546.     CHECKVALID( VOID );
  1547.     
  1548.     SOM_TRY
  1549.         TempODFrame embeddedFrame = somSelf;
  1550.         TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1551.         
  1552.         embeddedFrame->Acquire(ev); // will be released in loop below
  1553.         while ( containingFrame != kODNULL )
  1554.         {
  1555.             TempODPart containingPart = containingFrame->AcquirePart(ev);
  1556.             containingPart->EmbeddedFrameUpdated(ev, embeddedFrame, change);
  1557.             ODReleaseObject(ev, embeddedFrame);
  1558.             embeddedFrame = (ODFrame*) containingFrame; // do not bitwise copy!
  1559.             containingFrame = kODNULL; // avoid double Release in case following fails
  1560.             containingFrame = embeddedFrame->AcquireContainingFrame(ev);
  1561.         }
  1562.         ODReleaseObject(ev, embeddedFrame);
  1563.     SOM_CATCH_ALL
  1564.     SOM_ENDTRY
  1565. }
  1566.  
  1567. //------------------------------------------------------------------------------
  1568. // ODFrame: ChangeLinkStatus
  1569. //------------------------------------------------------------------------------
  1570.  
  1571. SOM_Scope void  SOMLINK ODFrameChangeLinkStatus(ODFrame *somSelf, Environment *ev,
  1572.         ODLinkStatus status)
  1573. {
  1574.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1575.     ODFrameMethodDebug("ODFrame","ChangeLinkStatus");
  1576.  
  1577.     CHECKVALID( VOID );
  1578.     
  1579.     SOM_TRY
  1580.         ODLinkStatus newStatus = _fLinkStatus;
  1581.         ODLinkStatus cfStatus = kODNotInLink;
  1582.  
  1583.         TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1584.         if ( containingFrame == kODNULL )
  1585.         {
  1586.             // Loop looking for a containing frame in case the this frame
  1587.             // turns out to be the root frame of a part window.
  1588.             // This code may be executed on a frame that has no containing
  1589.             // frame, yet is not a root window frame, so this must not
  1590.             // assume the frame has a window (#1379355). [cc]
  1591.             TempODFrame sourceFrame = somSelf;
  1592.             sourceFrame->Acquire(ev); // because it will be Released below
  1593.             do
  1594.             {
  1595.                 TempODWindow tempWindow = sourceFrame->AcquireWindow(ev);
  1596.                 ODReleaseObject(ev, sourceFrame);    // Sets sourceFrame to kODNULL [cc]
  1597.                 if ( (ODWindow*) tempWindow )
  1598.                 {
  1599.                     sourceFrame = tempWindow->AcquireSourceFrame(ev);
  1600.                     if ( sourceFrame )
  1601.                     {
  1602.                         containingFrame = sourceFrame->AcquireContainingFrame(ev);
  1603.                     }
  1604.                 }
  1605.             }
  1606.             while ( (containingFrame == kODNULL) && (sourceFrame != kODNULL) );
  1607.         }
  1608.  
  1609.         if ( containingFrame )
  1610.         {
  1611.             cfStatus = containingFrame->GetLinkStatus(ev);
  1612.         }
  1613.  
  1614.         if ( (status != kODNotInLink)
  1615.                 && (status != kODInLinkSource)
  1616.                 && (status != kODInLinkDestination) )
  1617.             THROW(kODErrInvalidLinkStatus);        
  1618.         
  1619.         // the logic below will automatically fix the link status of an embedded
  1620.         // frame to be at least as restrictive as the status of its containing frame
  1621.         if ( cfStatus == kODNotInLink )
  1622.         {
  1623.             newStatus = status;
  1624.         }
  1625.         else if ( cfStatus == kODInLinkSource )
  1626.         {
  1627.             if ( status == kODInLinkDestination )
  1628.                 newStatus = kODInLinkDestination;
  1629.             else
  1630.                 newStatus = kODInLinkSource;
  1631.         }
  1632.         else if ( cfStatus == kODInLinkDestination )
  1633.         {
  1634.             newStatus = kODInLinkDestination;
  1635.         }
  1636.         else
  1637.             THROW(kODErrInvalidLinkStatus);        
  1638.         
  1639.         if ( _fLinkStatus != newStatus )
  1640.         {
  1641.             _fLinkStatus = newStatus;
  1642.             TempODPart tempPart = somSelf->AcquirePart(ev);
  1643.             tempPart->LinkStatusChanged(ev, somSelf);
  1644.     
  1645.             somSelf->SetDirty(ev, kLinkStatusDirty);
  1646.         }
  1647.  
  1648.     SOM_CATCH_ALL
  1649.     SOM_ENDTRY
  1650. }
  1651.  
  1652. //------------------------------------------------------------------------------
  1653. // ODFrame: GetLinkStatus
  1654. //------------------------------------------------------------------------------
  1655.  
  1656. SOM_Scope ODLinkStatus  SOMLINK ODFrameGetLinkStatus(ODFrame *somSelf, Environment *ev)
  1657. {
  1658.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1659.     ODFrameMethodDebug("ODFrame","GetLinkStatus");
  1660.  
  1661.     CHECKVALID(kODFalse);
  1662.     
  1663.     return _fLinkStatus;
  1664. }
  1665.  
  1666. //------------------------------------------------------------------------------
  1667. // ODFrame: EditInLink
  1668. //------------------------------------------------------------------------------
  1669.  
  1670. SOM_Scope ODBoolean  SOMLINK ODFrameEditInLink(ODFrame *somSelf, Environment *ev)
  1671. {
  1672.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1673.     ODFrameMethodDebug("ODFrame","EditInLink");
  1674.  
  1675.     CHECKVALID(kODFalse);
  1676.     
  1677.     ODBoolean success = kODFalse;    ODVolatile(success);
  1678.  
  1679.     SOM_TRY    
  1680.         if ( _fLinkStatus == kODInLinkDestination )
  1681.         {
  1682.             TempODFrame lastFrame = somSelf;
  1683.             lastFrame->Acquire(ev); // because it will be Released below
  1684.             while ( kODTrue )
  1685.             {
  1686.                 TempODFrame nextFrame = lastFrame->AcquireContainingFrame(ev);
  1687.                 if ( nextFrame == kODNULL )
  1688.                 {
  1689.                     TempODWindow tempWindow = lastFrame->AcquireWindow(ev);
  1690.                     if ( (ODWindow*) tempWindow )
  1691.                     {
  1692.                         nextFrame = tempWindow->AcquireSourceFrame(ev);
  1693.                     }
  1694.                 }
  1695.                 if ( nextFrame == kODNULL )
  1696.                     break;
  1697.                 
  1698.                 // the test below should never be true if nextFrame is lastFrame's
  1699.                 // sourceFrame, therefore below nextFrame will always be the
  1700.                 // containing frame of lastFrame
  1701.                 if ( nextFrame->GetLinkStatus(ev) != kODInLinkDestination )
  1702.                 {
  1703.                     TempODPart tempPart = nextFrame->AcquirePart(ev);
  1704.                     success = tempPart->EditInLinkAttempted(ev, lastFrame);
  1705.                     break;
  1706.                 }
  1707.                 else
  1708.                 {
  1709.                     ODReleaseObject(ev, lastFrame);
  1710.                     lastFrame = (ODFrame*) nextFrame; // do not bitwise copy!
  1711.                     nextFrame = kODNULL; // to prevent Release on loop
  1712.                 }
  1713.             }
  1714.         }
  1715.     SOM_CATCH_ALL
  1716.         success = kODFalse;
  1717.     SOM_ENDTRY
  1718.     return success;
  1719. }
  1720.  
  1721. //------------------------------------------------------------------------------
  1722. // ODFrame: Invalidate
  1723. //------------------------------------------------------------------------------
  1724.  
  1725. SOM_Scope void  SOMLINK ODFrameInvalidate(ODFrame *somSelf, Environment *ev,
  1726.         ODShape* invalidShape, ODCanvas* biasCanvas)
  1727. {
  1728.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1729.     ODFrameMethodDebug("ODFrame","Invalidate");
  1730.  
  1731.     CHECKVALID( VOID );
  1732.     
  1733.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1734.     SOM_TRY
  1735.         i = somSelf->CreateFacetIterator(ev);    
  1736.         for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1737.             facet->Invalidate(ev, invalidShape, biasCanvas);
  1738.         delete i;
  1739.     SOM_CATCH_ALL
  1740.         ODDeleteObject(i);
  1741.     SOM_ENDTRY
  1742. }
  1743.  
  1744. //------------------------------------------------------------------------------
  1745. // ODFrame: Validate
  1746. //------------------------------------------------------------------------------
  1747.  
  1748. SOM_Scope void  SOMLINK ODFrameValidate(ODFrame *somSelf, Environment *ev,
  1749.         ODShape* validShape, ODCanvas* biasCanvas)
  1750. {
  1751.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1752.     ODFrameMethodDebug("ODFrame","Validate");
  1753.  
  1754.     CHECKVALID( VOID );
  1755.     
  1756.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1757.     SOM_TRY
  1758.         i = somSelf->CreateFacetIterator(ev);    
  1759.         for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1760.             facet->Validate(ev, validShape, biasCanvas);
  1761.         delete i;
  1762.     SOM_CATCH_ALL
  1763.         ODDeleteObject(i);
  1764.     SOM_ENDTRY
  1765. }
  1766.  
  1767.  
  1768. //------------------------------------------------------------------------------
  1769. // ODFrame: InvalidateActiveBorder
  1770. //------------------------------------------------------------------------------
  1771. SOM_Scope void  SOMLINK ODFrameInvalidateActiveBorder(ODFrame *somSelf, Environment *ev)
  1772. {
  1773.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1774.     ODFrameMethodDebug("ODFrame","InvalidateActiveBorder");
  1775.  
  1776.     CHECKVALID( VOID );
  1777.     
  1778.     if ( _fIsRoot )        // don't draw for root frame with subframes
  1779.         return;
  1780.     
  1781.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1782.     SOM_TRY
  1783.         if ( _fIsSubframe )
  1784.         {
  1785.             // don't draw for subframes. instead, have containingFrame draw
  1786.             TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1787.             containingFrame->InvalidateActiveBorder(ev);
  1788.         }
  1789.         else
  1790.         {
  1791.             // draw active border on all my facets
  1792.             i = somSelf->CreateFacetIterator(ev);
  1793.             for ( ODFacet* facet = i->First(ev);
  1794.                     i->IsNotComplete(ev);
  1795.                     facet = i->Next(ev) )
  1796.             {
  1797.                 facet->InvalidateActiveBorder(ev);
  1798.             }
  1799.             ODDeleteObject(i);
  1800.         }
  1801.     SOM_CATCH_ALL
  1802.         ODDeleteObject(i);
  1803.     SOM_ENDTRY
  1804. }
  1805.  
  1806. //------------------------------------------------------------------------------
  1807. // ODFrame: DrawActiveBorder
  1808. //------------------------------------------------------------------------------
  1809.  
  1810. SOM_Scope void  SOMLINK ODFrameDrawActiveBorder(ODFrame *somSelf, Environment *ev)
  1811. {
  1812.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1813.     ODFrameMethodDebug("ODFrame","DrawActiveBorder");
  1814.  
  1815.     CHECKVALID( VOID );
  1816.     
  1817.     if ( _fIsRoot )        // don't draw for root frame with subframes
  1818.         return;
  1819.  
  1820.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1821.     SOM_TRY
  1822.         if ( _fIsSubframe )
  1823.         {
  1824.             // don't draw for subframes. instead, have containingFrame draw
  1825.             TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  1826.             containingFrame->DrawActiveBorder(ev);
  1827.         }
  1828.         else
  1829.         {
  1830.             // draw active border on all my facets
  1831.             i = somSelf->CreateFacetIterator(ev);
  1832.             for ( ODFacet* facet = i->First(ev);
  1833.                     i->IsNotComplete(ev);
  1834.                     facet = i->Next(ev) )
  1835.             {
  1836.                 facet->DrawActiveBorder(ev);
  1837.             }
  1838.             delete i;
  1839.         }
  1840.     SOM_CATCH_ALL
  1841.         ODDeleteObject(i);
  1842.     SOM_ENDTRY
  1843. }
  1844.  
  1845. //------------------------------------------------------------------------------
  1846. // ODFrame: Release
  1847. //------------------------------------------------------------------------------
  1848.  
  1849. SOM_Scope void  SOMLINK ODFrameRelease(ODFrame *somSelf, Environment *ev)
  1850. {
  1851.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1852.     ODFrameMethodDebug("ODFrame","Release");
  1853.  
  1854.     // *DON'T* CHECKVALID - need to be able to release invalid frames
  1855.  
  1856.     SOM_TRY
  1857.         if ( (somSelf->GetRefCount(ev) == 1) &&
  1858.             (_fValidState & kFrameIsRemoved) &&
  1859.             !(_fValidState & kFrameIsInRelease) &&
  1860.             somSelf->GetStorageUnit(ev) )
  1861.         {
  1862.             // remove persistent frames previously removed which are
  1863.             // finally unreferenced
  1864.             _fValidState |= kFrameIsInRelease;
  1865.             _fDraft->RemoveFrame(ev, somSelf);
  1866.         }
  1867.         else
  1868.         {
  1869.             parent_Release(somSelf, ev);
  1870.             if (somSelf->GetRefCount(ev) == 0)
  1871.             {
  1872.                 // only release frames previously closed or non-persistent
  1873.                 _fDraft->ReleaseFrame(ev, somSelf);
  1874.                 _fValidState &= ~kFrameIsInRelease;
  1875.             }
  1876.         }
  1877.     SOM_CATCH_ALL
  1878.     SOM_ENDTRY
  1879. }
  1880.  
  1881. //------------------------------------------------------------------------------
  1882. // ODFrame: Close
  1883. //------------------------------------------------------------------------------
  1884.  
  1885. SOM_Scope void  SOMLINK ODFrameClose(ODFrame *somSelf, Environment *ev)
  1886. {
  1887.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1888.     ODFrameMethodDebug("ODFrame","Close");
  1889.  
  1890.     CHECKVALID( VOID );
  1891.  
  1892.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1893.  
  1894.     SOM_TRY
  1895.         if ( _fPart ) // if fPart not already internalized, don't force it
  1896.         {
  1897.             i = somSelf->CreateFacetIterator(ev);
  1898.             for (ODFacet* facet = i->First(ev); i->IsNotComplete(ev); facet = i->Next(ev))
  1899.                 _fPart->FacetRemoved(ev, facet);
  1900.             ODDeleteObject(i);
  1901.         
  1902.             TRY
  1903.                 _fPart->DisplayFrameClosed(ev, somSelf);
  1904.             CATCH_ALL
  1905.                 WARN("Part returned err %d closing frame",ErrorCode());
  1906.                 // don't reraise
  1907.             ENDTRY
  1908.             ODReleaseObject(ev,_fPart);
  1909.         }
  1910.         ODReleaseObject(ev, _fContainingFrame);
  1911.         ODReleaseObject(ev, _fWindow);
  1912.         somSelf->Release(ev);
  1913.     SOM_CATCH_ALL
  1914.         ODDeleteObject(i);
  1915.     SOM_ENDTRY
  1916. }
  1917.  
  1918. //------------------------------------------------------------------------------
  1919. // ODFrame: Remove
  1920. //------------------------------------------------------------------------------
  1921.  
  1922. SOM_Scope void  SOMLINK ODFrameRemove(ODFrame *somSelf, Environment *ev)
  1923. {
  1924.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1925.     ODFrameMethodDebug("ODFrame","Remove");
  1926.  
  1927.     CHECKVALID( VOID );
  1928.  
  1929.     ODFrameFacetIterator* i = kODNULL; ODVolatile(i);
  1930.  
  1931.     SOM_TRY
  1932.         if ( _fPart == kODNULL )
  1933.             somSelf->AcquirePart(ev)->Release(ev);    // force internalization of fPart
  1934.  
  1935.         if ( _fFacets->Count() != 0 )
  1936.             THROW(kODErrFrameHasFacets);
  1937.         
  1938.         TRY
  1939.             _fPart->DisplayFrameRemoved(ev, somSelf);
  1940.         CATCH_ALL
  1941.             WARN("Part returned err %d removing frame",ErrorCode());
  1942.             // don't reraise
  1943.         ENDTRY
  1944.         
  1945.         ODReleaseObject(ev, _fPart);
  1946.         ODReleaseObject(ev, _fContainingFrame);
  1947.         ODReleaseObject(ev, _fWindow);
  1948.         
  1949.         // Disassociate the object from its persistent ID now, in case
  1950.         // our draft's RemoveFrame method can't be called yet due to
  1951.         // outstanding references. [cc]
  1952.         _fDraft->DropPersistentObjectID(ev, somSelf);
  1953.  
  1954.         if (somSelf->GetRefCount(ev) == 1)
  1955.         {
  1956.             _fDraft->RemoveFrame(ev, somSelf);
  1957.         }
  1958.         else
  1959.         {
  1960.             somSelf->Release(ev);
  1961.             _fValidState = kFrameIsRemoved;
  1962.         }
  1963.     SOM_CATCH_ALL
  1964.         ODDeleteObject(i);
  1965.     SOM_ENDTRY
  1966. }
  1967.  
  1968. //------------------------------------------------------------------------------
  1969. // ODFrame: Purge
  1970. //------------------------------------------------------------------------------
  1971.  
  1972. SOM_Scope ODSize  SOMLINK ODFramePurge(ODFrame *somSelf, Environment *ev,
  1973.         ODSize numBytes)
  1974. {
  1975.     ODFrameData *somThis = ODFrameGetData(somSelf);
  1976.     ODFrameMethodDebug("ODFrame","Purge");
  1977.  
  1978.     // *DON'T* CHECKVALID - still need to purge invalid frames
  1979.  
  1980.     ODSize freed = 0;                    ODVolatile(freed);
  1981.     ODFrameFacetIterator* i = kODNULL;    ODVolatile(i);
  1982.  
  1983.     SOM_TRY
  1984.         // purge geometric objects
  1985.         if ( _fFrameShape != kODNULL )
  1986.             freed += _fFrameShape->Purge(ev, numBytes-freed);
  1987.         if ( _fUsedShape != kODNULL )
  1988.             freed += _fUsedShape->Purge(ev, numBytes-freed);
  1989.         if ( _fInternalTransform != kODNULL )
  1990.             freed += _fInternalTransform->Purge(ev, numBytes-freed);
  1991.         
  1992.         if ( _fValidState == kFrameIsValid )
  1993.         {
  1994.             // purge facets
  1995.             i = new ODFrameFacetIterator;
  1996.             THROW_IF_NULL(i);
  1997.             i->InitFrameFacetIterator(ev, somSelf);
  1998.             for ( ODFacet* facet = i->First(ev);
  1999.                     i->IsNotComplete(ev);
  2000.                     facet = i->Next(ev) )
  2001.             {
  2002.                 freed += facet->Purge(ev, numBytes-freed);
  2003.             }
  2004.             ODDeleteObject(i);
  2005.         }
  2006.         
  2007.         // dh - call parent's purge method
  2008.         freed += parent_Purge(somSelf, ev, numBytes);
  2009.         
  2010.     SOM_CATCH_ALL
  2011.         ODDeleteObject(i);
  2012.         WARN("Error %ld trying to purge in ODFramePurge",ErrorCode());
  2013.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  2014.                                         // propagate it because clients function
  2015.                                         // fine whether memory was purged or not.
  2016.     SOM_ENDTRY
  2017.  
  2018.     return freed;
  2019. }
  2020.  
  2021. //------------------------------------------------------------------------------
  2022. // WriteShapeIfAny  [static]
  2023. //------------------------------------------------------------------------------
  2024.  
  2025. static void
  2026. WriteShapeIfAny( Environment *ev, ODStorageUnit *su, ODShape *shape, ODPropertyName property )
  2027. {
  2028.     if (shape) {
  2029.         su->Focus(ev, property, kODPosUndefined, kODNULL, (ODValueIndex)0, kODPosUndefined);
  2030.          shape->WriteShape(ev, su);
  2031.     } else if (su->Exists(ev, property, kODNULL, 1)) {
  2032.         su->Focus(ev, property, kODPosUndefined, kODNULL, (ODValueIndex)1, kODPosUndefined);
  2033.         su->DeleteValue(ev, su->GetSize(ev));
  2034.     }
  2035. }
  2036.  
  2037. //------------------------------------------------------------------------------
  2038. // ODFrame: Externalize
  2039. //------------------------------------------------------------------------------
  2040.  
  2041. SOM_Scope void  SOMLINK ODFrameExternalize(ODFrame *somSelf, Environment *ev)
  2042. {
  2043.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2044.     ODFrameMethodDebug("ODFrame","Externalize");
  2045.  
  2046.     // *DON'T* CHECKVALID - need to write an "I'm invalid" representation
  2047.  
  2048.     SOM_TRY
  2049.         ODStorageUnit* su = kODNULL;
  2050.         ODSession* session = kODNULL;
  2051.         ODISOStr typeString = kODNULL;
  2052.         
  2053.         su = somSelf->GetStorageUnit(ev);
  2054.         if ( su == kODNULL) return;        // don't externalize non-persistent frames
  2055.         
  2056.         parent_Externalize(somSelf, ev);
  2057.     
  2058.         session = su->GetSession(ev);
  2059.         
  2060.         // if frame is invalid because of removal, delete Part property to
  2061.         // indicate persistently that frame is invalid.
  2062.         if ( _fDirty && _fValidState )
  2063.         {
  2064.             ODSURemoveProperty(ev, su, kODPropPart);
  2065.             ODSURemoveProperty(ev, su, kODPropContainingFrame);
  2066.             _fDirty = kNotDirty;
  2067.             return;
  2068.         }
  2069.     
  2070.         if ( _fDirty & kContainingFrameDirty )
  2071.         {
  2072.             // can't write suRef to non-persistent containingFrame
  2073.             if ( _fContainingFrame && _fContainingFrame->GetStorageUnit(ev) )
  2074.                 ODSetWeakSURefProp(ev, su, kODPropContainingFrame, kODWeakStorageUnitRef, 
  2075.                                     _fContainingFrame->GetStorageUnit(ev)->GetID(ev));
  2076.             else
  2077.             {
  2078.                 if ( ODSUExistsThenFocus(ev, su, kODPropContainingFrame, kODWeakStorageUnitRef) )
  2079.                     su->Remove(ev);
  2080.                 ODSUAddPropValue(ev, su, kODPropContainingFrame, kODWeakStorageUnitRef);
  2081.             }
  2082.         }
  2083.         
  2084.         // geometry
  2085.         
  2086.         // no bias transform needed, already in standard bias
  2087.         ODSURemoveProperty(ev, su, kODPropBiasTransform);
  2088.     
  2089.         if ( _fDirty & kFrameShapeDirty )
  2090.         {
  2091.             su->Focus(ev, kODPropFrameShape, kODPosUndefined, kODNULL, (ODValueIndex)0, kODPosUndefined);
  2092.             _fFrameShape->WriteShape(ev, su);
  2093.         }
  2094.         
  2095.         if ( _fDirty & kInternalTransformDirty )
  2096.         {
  2097.             su->Focus(ev, kODPropInternalTransform, kODPosUndefined, kODNULL, (ODValueIndex)0, kODPosUndefined);
  2098.             _fInternalTransform->WriteTo(ev, su);
  2099.         }
  2100.         
  2101.         // part & partInfo
  2102.         
  2103.         if ( _fDirty & kPartDirty )
  2104.         {
  2105.             ASSERT( _fPart, kODErrInvalidFrame);
  2106.             ODSetStrongSURefProp(ev, su, kODPropPart, kODStrongStorageUnitRef, _fPart->GetID(ev));
  2107.         }
  2108.         
  2109.         // always try to write partInfo, part knows if it's dirty
  2110.         if ( _fPart ) // only have to write partInfo if part has been internalized
  2111.         {
  2112.             su->Focus(ev, kODPropPartInfo, kODPosUndefined, kODNULL, (ODValueIndex)0, kODPosUndefined);
  2113.             TempODStorageUnitView suView = su->CreateView(ev);
  2114.             _fPart->WritePartInfo(ev, (ODInfoType)_fPartInfo, suView);
  2115.         }
  2116.         
  2117.         // viewType & presentation
  2118.         
  2119.         if ( _fDirty & kViewTypeDirty )
  2120.         {
  2121.             if ( (_fViewType != kODNULL) && session->GetType(ev, _fViewType, &typeString) )
  2122.             {
  2123.                 ODSetISOStrProp(ev, su, kODPropViewType, kODISOStr, typeString);
  2124.                 delete typeString; typeString = kODNULL;
  2125.             }
  2126.         }
  2127.         
  2128.         if ( _fDirty & kPresentationDirty )
  2129.         {
  2130.             if ( (_fPresentation != kODNULL) && session->GetType(ev, _fPresentation, &typeString) )
  2131.             {
  2132.                 ODSetISOStrProp(ev, su, kODPropPresentation, kODISOStr, typeString);
  2133.                 delete typeString; typeString = kODNULL;
  2134.             }
  2135.         }
  2136.         
  2137.         if ( _fDirty & kFrameGroupDirty )
  2138.             ODSetULongProp(ev, su, kODPropFrameGroup, kODULong, _fFrameGroup);
  2139.         if ( _fDirty & kSequenceNumberDirty )
  2140.             ODSetULongProp(ev, su, kODPropSequenceNumber, kODULong, _fSequenceNumber);
  2141.         if ( _fDirty & kLinkStatusDirty )
  2142.             ODSetULongProp(ev, su, kODPropLinkStatus, kODULong, _fLinkStatus);
  2143.     
  2144.         if ( _fDirty & kFlagsDirty )
  2145.         {
  2146.             ODSetBooleanProp(ev, su, kODPropIsSubframe, kODBoolean, _fIsSubframe);
  2147.             ODSetBooleanProp(ev, su, kODPropIsOverlaid, kODBoolean, _fIsOverlaid);
  2148.             ODSetBooleanProp(ev, su, kODPropIsFrozen, kODBoolean, _fIsFrozen);
  2149.         }
  2150.     
  2151.         _fDirty = kNotDirty;
  2152.     SOM_CATCH_ALL
  2153.     SOM_ENDTRY
  2154. }
  2155.  
  2156. //------------------------------------------------------------------------------
  2157. // ODFrame: CloneInto
  2158. //------------------------------------------------------------------------------
  2159.  
  2160. SOM_Scope void  SOMLINK ODFrameCloneInto(ODFrame *somSelf, Environment *ev,
  2161.         ODDraftKey key,
  2162.         ODStorageUnit* toSU,
  2163.         ODFrame* scopeFrame)
  2164. {
  2165.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2166.     ODFrameMethodDebug("ODFrame","CloneInto");
  2167.  
  2168.     // *DON'T* CHECKVALID - need to write an "I'm invalid" representation
  2169.  
  2170.     SOM_TRY    
  2171.         if ( kODNULL == toSU ) THROW(kODErrIllegalNullInput);
  2172.     
  2173.         ODStorageUnitID        fromSUID = somSelf->GetID(ev);
  2174.         ODDraft*            fromDraft = _fDraft;
  2175.         ODISOStr            typeString = kODNULL;
  2176.     
  2177.         if (toSU->Exists(ev, kODPropFrameShape, kODNULL, 0) == kODFalse)
  2178.         {
  2179.             parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  2180.             
  2181.             // if frame is invalid because of removal, don't write Part
  2182.             // Property to indicate that frame is invalid.
  2183.             if ( _fValidState )
  2184.                 return;
  2185.  
  2186.             if (_fContainingFrame)
  2187.             {
  2188.                 ODID toContainingFrameID = fromDraft->WeakClone(ev, key, _fContainingFrame->GetID(ev), 0, 0);
  2189.                 ODSetWeakSURefProp(ev, toSU, kODPropContainingFrame, kODWeakStorageUnitRef, 
  2190.                                     toContainingFrameID);
  2191.             }
  2192.             
  2193.             toSU->AddProperty(ev, kODPropFrameShape);
  2194.             _fFrameShape->WriteShape(ev, toSU);
  2195.             
  2196.             ODSUAddPropValue(ev, toSU, kODPropInternalTransform, kODTransform);
  2197.             _fInternalTransform->WriteTo(ev, toSU);
  2198.             
  2199.             // part & partInfo
  2200.             
  2201.             if ( _fPart == kODNULL )
  2202.                 somSelf->AcquirePart(ev)->Release(ev); // force internalization of fPart
  2203.  
  2204.             ODID toPartID = fromDraft->Clone(ev, key, _fPart->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  2205.             ODSetStrongSURefProp(ev, toSU, kODPropPart, kODStrongStorageUnitRef, toPartID);
  2206.         
  2207.             toSU->AddProperty(ev, kODPropPartInfo);
  2208.             {
  2209.                 TempODStorageUnitView suView = toSU->CreateView(ev);
  2210.                 _fPart->ClonePartInfo(ev, key, (ODInfoType)_fPartInfo, suView, scopeFrame);
  2211.             }
  2212.             
  2213.     
  2214.             // Window Properties
  2215.             ODStorageUnit* fromSU = somSelf->GetStorageUnit(ev);
  2216.             if (fromSU && _fIsRoot)
  2217.             {
  2218.                 ODID windowPropsID;
  2219.                 if ((windowPropsID = ODGetStrongSURefProp(ev, fromSU, kODPropWindowProperties, kODStrongStorageUnitRef))
  2220.                     != 0)
  2221.                 {                
  2222.                     ODID toWindowPropsID = fromDraft->Clone(ev, key, windowPropsID, 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  2223.                     ODSetStrongSURefProp(ev, toSU, kODPropWindowProperties, kODStrongStorageUnitRef, toWindowPropsID);
  2224.                 }
  2225.             }
  2226.             // viewType & presentation
  2227.             
  2228.             ODSession* session = toSU->GetSession(ev);
  2229.             
  2230.             ASSERT(_fViewType, kODErrInvalidFrame);
  2231.             if ( (_fViewType != kODNULL) && session->GetType(ev, _fViewType, &typeString) )
  2232.             {
  2233.                 ODSetISOStrProp(ev, toSU, kODPropViewType, kODISOStr, typeString);
  2234.                 delete typeString; typeString = kODNULL;
  2235.             }
  2236.         
  2237.             ASSERT(_fPresentation, kODErrInvalidFrame);
  2238.             if ( (_fPresentation != kODNULL) && session->GetType(ev, _fPresentation, &typeString) )
  2239.             {
  2240.                 ODSetISOStrProp(ev, toSU, kODPropPresentation, kODISOStr, typeString);
  2241.                 delete typeString; typeString = kODNULL;
  2242.             }
  2243.         
  2244.             ODSetULongProp(ev, toSU, kODPropFrameGroup, kODULong, _fFrameGroup);
  2245.             ODSetULongProp(ev, toSU, kODPropSequenceNumber, kODULong, _fSequenceNumber);
  2246.             ODSetULongProp(ev, toSU, kODPropLinkStatus, kODULong, _fLinkStatus);
  2247.             ODSetBooleanProp(ev, toSU, kODPropIsSubframe, kODBoolean, _fIsSubframe);
  2248.             ODSetBooleanProp(ev, toSU, kODPropIsOverlaid, kODBoolean, _fIsOverlaid);
  2249.             ODSetBooleanProp(ev, toSU, kODPropIsFrozen, kODBoolean, _fIsFrozen);
  2250.         }
  2251.         else
  2252.         {
  2253.             if ( _fPart == kODNULL )
  2254.                 somSelf->AcquirePart(ev)->Release(ev); // force internalization of fPart
  2255.             ODID toPartID = fromDraft->Clone(ev, key, _fPart->GetID(ev), 0, (scopeFrame ? scopeFrame->GetID(ev) : 0));
  2256.         }
  2257.     SOM_CATCH_ALL
  2258.     SOM_ENDTRY
  2259. }
  2260.  
  2261. //------------------------------------------------------------------------------
  2262. // ODFrame: GetFacets
  2263. //------------------------------------------------------------------------------
  2264.  
  2265. SOM_Scope OrderedCollection*  SOMLINK ODFrameGetFacets(ODFrame *somSelf, Environment *ev)
  2266. {
  2267.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2268.     ODFrameMethodDebug("ODFrame","GetFacets");
  2269.  
  2270.     CHECKVALID(kODNULL);
  2271.  
  2272.     return _fFacets;
  2273. }
  2274.  
  2275. //------------------------------------------------------------------------------
  2276. // ODFrame: PrepareToSwap
  2277. //------------------------------------------------------------------------------
  2278.  
  2279. SOM_Scope void  SOMLINK ODFramePrepareToSwap(ODFrame *somSelf, Environment *ev,
  2280.         ODPart* part)
  2281. {
  2282.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2283.     ODFrameMethodDebug("ODFrame","PrepareToSwap");
  2284.  
  2285.     CHECKVALID( VOID );
  2286.  
  2287.     SOM_TRY
  2288.         ODBoolean swappingMyPart = kODFalse;
  2289.         
  2290.         if ( _fPart )
  2291.             swappingMyPart = ODObjectsAreEqual(ev, part, _fPart);
  2292.         else
  2293.         {
  2294.             ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  2295.             if ( su )
  2296.             {
  2297.                 ODID myPartID = ODGetStrongSURefProp(ev, su, kODPropPart,
  2298.                                                         kODStrongStorageUnitRef);
  2299.                 swappingMyPart = ( part->GetID(ev) == myPartID );
  2300.             }
  2301.         }
  2302.         
  2303.         if ( swappingMyPart )
  2304.         {
  2305.             if ( _fIsRoot && _fWindow )
  2306.             {
  2307.                 _fWindow->Acquire(ev);    // balanced by Release in Close below
  2308.                 _fWindow->Close(ev);
  2309.                 _fWindow = kODNULL;
  2310.             }
  2311.             else
  2312.             {
  2313.                 somSelf->Acquire(ev);  // because Close calls Release on self
  2314.                 somSelf->Close(ev);
  2315.                 somSelf->Invalidate(ev,kODNULL,kODNULL);
  2316.                 
  2317.                 // When we swap an embedded part we want to invalidate the facet 
  2318.                 // hierarchy associated with this frame so that the part swapped
  2319.                 // in will get a draw message.
  2320.             }
  2321.         }
  2322.     SOM_CATCH_ALL
  2323.     SOM_ENDTRY
  2324. }
  2325.  
  2326.  
  2327. //------------------------------------------------------------------------------
  2328. // ODFrame: SetDirty
  2329. //------------------------------------------------------------------------------
  2330.  
  2331. SOM_Scope void  SOMLINK ODFrameSetDirty(ODFrame *somSelf, Environment *ev,
  2332.                                         ODULong dirtyProperty)
  2333. {
  2334.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2335.     ODFrameMethodDebug("ODFrame","SetDirty");
  2336.  
  2337.     SOM_TRY
  2338.         if ( somSelf->GetStorageUnit(ev) ) // don't set non-persistent frames dirty
  2339.         {
  2340.             _fDirty |= dirtyProperty;
  2341.             if ( dirtyProperty & kIncidentalDirty ) // change was only incidental?
  2342.                 /* do not mark draft dirty */;
  2343.             else
  2344.             {
  2345.                 // significant changes cause draft to be dirtied if modifiable:
  2346.                 if (HAS_WRITE_ACCESS(_fDraft->GetPermissions(ev)))
  2347.                 {
  2348.                     _fDraft->SetChangedFromPrev(ev);
  2349.                 }
  2350.             }
  2351.         }
  2352.     SOM_CATCH_ALL
  2353.     SOM_ENDTRY
  2354. }
  2355.  
  2356. //------------------------------------------------------------------------------
  2357. // ODFrame: CommonInitFrame
  2358. //------------------------------------------------------------------------------
  2359.  
  2360. SOM_Scope void  SOMLINK ODFrameCommonInitFrame(ODFrame *somSelf, Environment *ev)
  2361. {
  2362.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2363.     ODFrameMethodDebug("ODFrame","CommonInitFrame");
  2364.  
  2365.     SOM_TRY
  2366.         _fFacets = new OrderedCollection;
  2367.           THROW_IF_NULL(_fFacets);
  2368.     SOM_CATCH_ALL
  2369.     SOM_ENDTRY
  2370. }
  2371.  
  2372. //------------------------------------------------------------------------------
  2373. // ODFrame: InitFrame
  2374. //------------------------------------------------------------------------------
  2375. SOM_Scope void  SOMLINK ODFrameInitFrame(ODFrame *somSelf, Environment *ev,
  2376.         
  2377.                 ODStorageUnit*    storageUnit,
  2378.                 ODFrame*         containingFrame,
  2379.                 ODShape*         frameShape,
  2380.                 ODCanvas*        biasCanvas,
  2381.                 ODPart*         part,
  2382.                 ODTypeToken        viewType,
  2383.                 ODTypeToken        presentation,
  2384.                 ODBoolean        isSubframe,
  2385.                 ODBoolean         isOverlaid)
  2386. {
  2387.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2388.     ODFrameMethodDebug("ODFrame","InitFrame");
  2389.  
  2390.     /* Moved from somInit. SOM itself sets fields to zero
  2391.     _fDraft             = kODNULL;
  2392.     _fNPID                = 0;
  2393.     _fDirty                = kNotDirty;
  2394.  
  2395.     _fContainingFrame     = kODNULL;
  2396.     _fWindow             = kODNULL;
  2397.  
  2398.     _fFrameShape        = (ODShape*) kODNULL;
  2399.     _fUsedShape            = (ODShape*) kODNULL;
  2400.  
  2401.     _fInternalTransform    = (ODTransform*) kODNULL;    
  2402.  
  2403.     _fFacets            = kODNULL;
  2404.  
  2405.     _fPart                = kODNULL;
  2406.     _fPartInfo            = (ODInfoType) kODNULL;
  2407.     _fViewType            = (ODTypeToken) 0;
  2408.     _fPresentation        = (ODTypeToken) 0;
  2409.  
  2410.     _fFrameGroup        = 0;
  2411.     _fSequenceNumber    = 0;
  2412.  
  2413.     _fLinkStatus        = kODNotInLink;
  2414.     _fIsRoot            = kODFalse;
  2415.     _fIsSubframe         = kODFalse;
  2416.     _fIsOverlaid          = kODFalse;
  2417.     _fIsFrozen             = kODFalse;
  2418.     _fIsDroppable         = kODFalse;
  2419.     _fIsDragging         = kODFalse;
  2420.     _fIsMoving             = kODFalse;
  2421.     _fDoesPropagateEvents =    kODFalse;
  2422.     */
  2423.     _fDirty                = kNotDirty;
  2424.     _fLinkStatus        = kODNotInLink;
  2425.     _fValidState        = kFrameIsValid;
  2426.     
  2427.     // *DON'T* CHECKVALID - new frames will never be invalid
  2428.     
  2429.     SOM_TRY
  2430.         if ( kODNULL == storageUnit )    THROW(kODErrIllegalNullStorageUnitInput);
  2431.         if ( kODNULL == frameShape    )    THROW(kODErrIllegalNullShapeInput);
  2432.         if ( kODNULL == part )            THROW(kODErrIllegalNullPartInput);
  2433.         if ( kODNULL == viewType )        THROW(kODErrIllegalNullTokenInput);
  2434.         if ( kODNULL == presentation )    THROW(kODErrIllegalNullTokenInput);
  2435.     
  2436.         // check for recursive embedding
  2437.         if ( (containingFrame != kODNULL) && !isSubframe )
  2438.         {
  2439.             TempODFrame tempFrame = containingFrame;
  2440.             tempFrame->Acquire(ev);   // because it will be released below
  2441.             while ( tempFrame )
  2442.             {
  2443.                 TempODPart tempPart = tempFrame->AcquirePart(ev);
  2444.                 if (tempPart == part)
  2445.                     THROW(kODErrIllegalRecursiveEmbedding);
  2446.                 ODFrame* spam = tempFrame;
  2447.                 TempODFrame oldFrame = spam;
  2448.                 tempFrame = kODNULL; // to avoid double Release if following fails
  2449.                 tempFrame = oldFrame->AcquireContainingFrame(ev);
  2450.             }
  2451.         }
  2452.         
  2453.         somSelf->InitPersistentObject(ev, storageUnit);
  2454.         _fDraft = storageUnit->GetDraft(ev);
  2455.         
  2456.         _fContainingFrame = containingFrame;
  2457.         ODAcquireObject(ev, _fContainingFrame);
  2458.     
  2459.         _fFrameShape = BiasShapeSet(ev, frameShape, biasCanvas);
  2460.         ODAcquireObject(ev, _fFrameShape);
  2461.     
  2462.         _fInternalTransform    = somSelf->CreateTransform(ev);
  2463.         _fContentExtent        = ODPoint(0,0);
  2464.     
  2465.         _fViewType        = viewType;
  2466.         _fPresentation    = presentation;
  2467.         _fIsRoot        = (containingFrame == kODNULL);
  2468.         _fIsSubframe    = isSubframe;
  2469.         _fIsOverlaid     = isOverlaid;
  2470.     
  2471.         somSelf->CommonInitFrame(ev);
  2472.         
  2473.         ODSUAddPropValue(ev, storageUnit, kODPropContainingFrame, kODWeakStorageUnitRef);
  2474.         ODSUAddPropValue(ev, storageUnit, kODPropFrameShape, kODPolygon);
  2475.         ODSUAddPropValue(ev, storageUnit, kODPropInternalTransform, kODTransform);
  2476.         ODSUAddPropValue(ev, storageUnit, kODPropPart, kODStrongStorageUnitRef);
  2477.     //    ODSUAddPropValue(ev, storageUnit, kODPropPartInfo, kODPartInfo);
  2478.         ODSUAddPropValue(ev, storageUnit, kODPropViewType, kODISOStr);
  2479.         ODSUAddPropValue(ev, storageUnit, kODPropPresentation, kODISOStr);
  2480.         ODSUAddPropValue(ev, storageUnit, kODPropFrameGroup, kODULong);
  2481.         ODSUAddPropValue(ev, storageUnit, kODPropSequenceNumber, kODULong);
  2482.         ODSUAddPropValue(ev, storageUnit, kODPropLinkStatus, kODULong);
  2483.         ODSUAddPropValue(ev, storageUnit, kODPropIsSubframe, kODBoolean);
  2484.         ODSUAddPropValue(ev, storageUnit, kODPropIsOverlaid, kODBoolean);
  2485.         ODSUAddPropValue(ev, storageUnit, kODPropIsFrozen, kODBoolean);
  2486.     
  2487.         _fPart = part;
  2488.         ODAcquireObject(ev, _fPart);
  2489.         _fPart->DisplayFrameAdded(ev, somSelf);
  2490.             
  2491.         somSelf->SetDirty(ev, kAllDirty);
  2492.     SOM_CATCH_ALL
  2493.     SOM_ENDTRY
  2494. }
  2495.  
  2496. //------------------------------------------------------------------------------
  2497. // ReadAndAcquireShapeIfAny  [static]
  2498. //------------------------------------------------------------------------------
  2499.  
  2500. static ODShape* // DMc refcount - include "acquire" in function name:
  2501. ReadAndAcquireShapeIfAny( Environment *ev, ODStorageUnit *su, ODPropertyName property )
  2502. {
  2503.     ODShape* shape = kODNULL;
  2504.     if( su->Exists(ev, property, kODNULL, 0) ) {
  2505.         shape= new ODShape;
  2506.           THROW_IF_NULL(shape);
  2507.         TRY{
  2508.             shape->InitShape(ev);
  2509.             su->Focus(ev, property, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  2510.             shape->ReadShape(ev, su);
  2511.         }CATCH_ALL{
  2512.             delete shape;
  2513.             RERAISE;
  2514.         }ENDTRY
  2515.     }
  2516.     return shape;
  2517. }
  2518.  
  2519. //------------------------------------------------------------------------------
  2520. // ReadAndAcquireTransformIfAny  [static]
  2521. //------------------------------------------------------------------------------
  2522.  
  2523. static ODTransform* // DMc refcount - include "acquire" in function name:
  2524. ReadAndAcquireTransformIfAny( Environment *ev, ODStorageUnit *su, ODPropertyName property )
  2525. {
  2526.     ODTransform* transform = kODNULL;
  2527.     if( su->Exists(ev, property, kODNULL, 0) ) {
  2528.         transform= new ODTransform;
  2529.           THROW_IF_NULL(transform);
  2530.         TRY{
  2531.             transform->InitTransform(ev);
  2532.             su->Focus(ev, property, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  2533.             transform->ReadFrom(ev, su);
  2534.         }CATCH_ALL{
  2535.             delete transform;
  2536.             RERAISE;
  2537.         }ENDTRY
  2538.     }
  2539.     return transform;
  2540. }
  2541.  
  2542. //------------------------------------------------------------------------------
  2543. // ODFrame: InitFrameFromStorage
  2544. //------------------------------------------------------------------------------
  2545.  
  2546. SOM_Scope void  SOMLINK ODFrameInitFrameFromStorage(ODFrame *somSelf, Environment *ev,
  2547.         ODStorageUnit*    storageUnit)
  2548. {
  2549.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2550.     ODFrameMethodDebug("ODFrame","InitFrameFromStorage");
  2551.  
  2552.     /* Moved from somInit. SOM itself sets fields to zero
  2553.     _fDraft             = kODNULL;
  2554.     _fNPID                = 0;
  2555.     _fDirty                = kNotDirty;
  2556.  
  2557.     _fContainingFrame     = kODNULL;
  2558.     _fWindow             = kODNULL;
  2559.  
  2560.     _fFrameShape        = (ODShape*) kODNULL;
  2561.     _fUsedShape            = (ODShape*) kODNULL;
  2562.  
  2563.     _fInternalTransform    = (ODTransform*) kODNULL;    
  2564.  
  2565.     _fFacets            = kODNULL;
  2566.  
  2567.     _fPart                = kODNULL;
  2568.     _fPartInfo            = (ODInfoType) kODNULL;
  2569.     _fViewType            = (ODTypeToken) 0;
  2570.     _fPresentation        = (ODTypeToken) 0;
  2571.  
  2572.     _fFrameGroup        = 0;
  2573.     _fSequenceNumber    = 0;
  2574.  
  2575.     _fLinkStatus        = kODNotInLink;
  2576.     _fIsRoot            = kODFalse;
  2577.     _fIsSubframe         = kODFalse;
  2578.     _fIsOverlaid          = kODFalse;
  2579.     _fIsFrozen             = kODFalse;
  2580.     _fIsDroppable         = kODFalse;
  2581.     _fIsDragging         = kODFalse;
  2582.     _fIsMoving             = kODFalse;
  2583.     _fDoesPropagateEvents =    kODFalse;
  2584.     */
  2585.     _fDirty                = kNotDirty;
  2586.     _fLinkStatus        = kODNotInLink;
  2587.     _fValidState        = kFrameIsValid;
  2588.  
  2589.     // *DON'T* CHECKVALID - need to read an "I'm invalid" representation
  2590.     
  2591.     SOM_TRY
  2592.         if (!storageUnit)
  2593.             THROW(kODErrIllegalNullStorageUnitInput);
  2594.             
  2595.         somSelf->InitPersistentObjectFromStorage(ev, storageUnit);
  2596.         _fDraft = storageUnit->GetDraft(ev);
  2597.     
  2598.     // mark this frame as invalid/removed if it was externalized without a part
  2599.     if ( !storageUnit->Exists(ev, kODPropPart, kODStrongStorageUnitRef, 0) )
  2600.     {
  2601.         _fValidState = kFrameIsRemoved;
  2602.         _fDirty = kNotDirty;
  2603.         return;
  2604.     }
  2605.     
  2606.         ASSERT(storageUnit->Exists(ev, kODPropFrameShape, kODPolygon, 0), kODErrInvalidPersistentFormat);
  2607.         ASSERT(storageUnit->Exists(ev, kODPropInternalTransform, kODTransform, 0), kODErrInvalidPersistentFormat);
  2608.         ASSERT(storageUnit->Exists(ev, kODPropViewType, kODISOStr, 0), kODErrInvalidPersistentFormat);
  2609.         ASSERT(storageUnit->Exists(ev, kODPropPresentation, kODISOStr, 0), kODErrInvalidPersistentFormat);
  2610.         ASSERT(storageUnit->Exists(ev, kODPropFrameGroup, kODULong, 0), kODErrInvalidPersistentFormat);
  2611.         ASSERT(storageUnit->Exists(ev, kODPropSequenceNumber, kODULong, 0), kODErrInvalidPersistentFormat);
  2612.         ASSERT(storageUnit->Exists(ev, kODPropIsSubframe, kODBoolean, 0), kODErrInvalidPersistentFormat);
  2613.         ASSERT(storageUnit->Exists(ev, kODPropIsOverlaid, kODBoolean, 0), kODErrInvalidPersistentFormat);
  2614.         ASSERT(storageUnit->Exists(ev, kODPropIsFrozen, kODBoolean, 0), kODErrInvalidPersistentFormat);
  2615.     
  2616.         // Note: kODPropLinkStatus is not a required property
  2617.  
  2618.         somSelf->CommonInitFrame(ev);
  2619.     
  2620.         ODULong valueSize = 0;
  2621.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  2622.         ODSession* session = su->GetSession(ev);
  2623.         ODType typeString;
  2624.     
  2625.         // don't internalize _fContainingFrame - be lazy and do it later
  2626.         
  2627.         // geometry - must use biasTransform to normalize
  2628.         
  2629.         TempODTransform biasTransform = // DMc refcount - make temp
  2630.             ReadAndAcquireTransformIfAny(ev, su, kODPropBiasTransform);
  2631.         
  2632.         _fFrameShape = ReadAndAcquireShapeIfAny(ev, su, kODPropFrameShape);
  2633.         if ( !_fFrameShape )
  2634.             THROW(kODErrInvalidPersistentFormat);
  2635.         if ( _fFrameShape && biasTransform )
  2636.             _fFrameShape->Transform(ev, biasTransform);
  2637.         
  2638.         _fInternalTransform = ReadAndAcquireTransformIfAny(ev, su, kODPropInternalTransform);
  2639.         if ( _fInternalTransform && biasTransform )
  2640.             _fInternalTransform->PreCompose(ev, biasTransform);
  2641.     
  2642.         // don't internalize _fPart or _fPartInfo
  2643.         
  2644.         // internalize viewType and presentation
  2645.     
  2646.         typeString = ODGetISOStrProp(ev, su, kODPropViewType, kODISOStr, kODNULL, &valueSize);
  2647.         if ( valueSize > 0 )
  2648.             _fViewType = session->Tokenize(ev, typeString);
  2649.         if (typeString)
  2650.             ODDisposePtr(typeString);
  2651.         
  2652.         typeString = ODGetISOStrProp(ev, su, kODPropPresentation, kODISOStr, kODNULL, &valueSize);
  2653.         if ( valueSize > 0 )
  2654.             _fPresentation = session->Tokenize(ev, typeString);
  2655.         if (typeString)
  2656.             ODDisposePtr(typeString);
  2657.         
  2658.         // _fIsRoot set if containingFrame is valid suRef
  2659.         if ( ODSUExistsThenFocus(ev, su, kODPropContainingFrame, kODWeakStorageUnitRef) )
  2660.         {
  2661.             ODStorageUnitRef value;
  2662.             StorageUnitGetValue(su, ev, kODStorageUnitRefLen, (ODValue)&value);
  2663.             _fIsRoot = !(su->IsValidStorageUnitRef(ev, value));
  2664.         }
  2665.         else
  2666.             _fIsRoot = kODTrue;
  2667.  
  2668.         
  2669.         _fFrameGroup      = ODGetULongProp(ev, su, kODPropFrameGroup, kODULong);
  2670.         _fSequenceNumber = ODGetULongProp(ev, su, kODPropSequenceNumber, kODULong);
  2671.         _fIsSubframe     = ODGetBooleanProp(ev, su, kODPropIsSubframe, kODBoolean);
  2672.         _fIsOverlaid     = ODGetBooleanProp(ev, su, kODPropIsOverlaid, kODBoolean);
  2673.         if (_fIsRoot)
  2674.             _fIsFrozen = kODFalse;
  2675.         else
  2676.             _fIsFrozen     = ODGetBooleanProp(ev, su, kODPropIsFrozen, kODBoolean);
  2677.     
  2678.         _fDirty = kNotDirty;
  2679.  
  2680.         if ( su->Exists(ev, kODPropLinkStatus, kODULong, 0) )
  2681.         {
  2682.             _fLinkStatus = ODGetULongProp(ev, su, kODPropLinkStatus, kODULong);
  2683.             if ( _fLinkStatus != kODNotInLink )
  2684.             {
  2685.                 // If this frame displays the root part of the draft,
  2686.                 // the link status SHOULD be kODNotInLink since it has no
  2687.                 // containing frame. (This is true even for subframes
  2688.                 // displaying the root part of the draft.) This frame
  2689.                 // was probably cloned from a document where it was
  2690.                 // embedded in a link. Force the link status back to kODNotInLink.
  2691.                 ODStorageUnitID    rootPartID, partID;
  2692.                 TempODStorageUnit draftProperties = _fDraft->AcquireDraftProperties(ev);
  2693.                 rootPartID = ODGetStrongSURefProp(ev, draftProperties,
  2694.                                 kODPropRootPartSU, kODStrongStorageUnitRef);
  2695.                 partID = ODGetStrongSURefProp(ev, su,
  2696.                                 kODPropPart, kODStrongStorageUnitRef);
  2697.                 if ( (partID != kODNULLID) && (rootPartID == partID) )
  2698.                 {
  2699.                      _fLinkStatus = kODNotInLink;
  2700.                     somSelf->SetDirty(ev, kLinkStatusDirty);
  2701.                 }
  2702.             }
  2703.         }
  2704.  
  2705.     SOM_CATCH_ALL
  2706.     SOM_ENDTRY
  2707. }
  2708.  
  2709. //------------------------------------------------------------------------------
  2710. // ODFrame: InitFrameNonPersistent
  2711. //------------------------------------------------------------------------------
  2712. SOM_Scope void  SOMLINK ODFrameInitFrameNonPersistent(ODFrame *somSelf, Environment *ev,
  2713.                 ODDraft*    draft,
  2714.                 ODID         id,
  2715.                 ODFrame*     containingFrame,
  2716.                 ODShape*     frameShape,
  2717.                 ODCanvas*    biasCanvas,
  2718.                 ODPart*     part,
  2719.                 ODTypeToken    viewType,
  2720.                 ODTypeToken    presentation,
  2721.                 ODBoolean    isSubframe,
  2722.                 ODBoolean     isOverlaid)
  2723. {
  2724.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2725.     ODFrameMethodDebug("ODFrame","InitFrameNonPersistent");
  2726.  
  2727.     // *DON'T* CHECKVALID - new frames will never be invalid
  2728.     
  2729.     SOM_TRY
  2730.         if ( kODNULL == draft )            THROW(kODErrIllegalNullStorageUnitInput);
  2731.         if ( kODNULL == frameShape    )    THROW(kODErrIllegalNullShapeInput);
  2732.         if ( kODNULL == part )            THROW(kODErrIllegalNullPartInput);
  2733.         if ( kODNULL == viewType )        THROW(kODErrIllegalNullTokenInput);
  2734.         if ( kODNULL == presentation )    THROW(kODErrIllegalNullTokenInput);
  2735.             
  2736.         // check for recursive embedding
  2737.         if ( (containingFrame != kODNULL) && !isSubframe )
  2738.         {
  2739.             TempODFrame tempFrame = containingFrame;
  2740.             tempFrame->Acquire(ev);   // because it will be released below
  2741.             while ( tempFrame )
  2742.             {
  2743.                 TempODPart tempPart = tempFrame->AcquirePart(ev);
  2744.                 if (tempPart == part)
  2745.                     THROW(kODErrIllegalRecursiveEmbedding);
  2746.                 ODFrame* spam = tempFrame;
  2747.                 TempODFrame oldFrame = spam;
  2748.                 tempFrame = kODNULL; // to avoid double Release if following fails
  2749.                 tempFrame = oldFrame->AcquireContainingFrame(ev);
  2750.             }
  2751.         }
  2752.  
  2753.         somSelf->InitPersistentObject(ev, kODNULL);
  2754.     
  2755.         _fLinkStatus = kODNotInLink;
  2756.         _fDraft = draft;
  2757.         _fNPID = id;
  2758.         
  2759.         _fContainingFrame = containingFrame;
  2760.         ODAcquireObject(ev, _fContainingFrame);
  2761.     
  2762.         _fFrameShape = BiasShapeSet(ev, frameShape, biasCanvas);
  2763.         ODAcquireObject(ev, _fFrameShape);
  2764.     
  2765.         _fInternalTransform    = somSelf->CreateTransform(ev);
  2766.         _fContentExtent        = ODPoint(0,0);
  2767.     
  2768.         _fViewType        = viewType;
  2769.         _fPresentation    = presentation;
  2770.         _fIsRoot        = (containingFrame == kODNULL);
  2771.         _fIsSubframe    = isSubframe;
  2772.         _fIsOverlaid     = isOverlaid;
  2773.     
  2774.         somSelf->CommonInitFrame(ev);
  2775.         
  2776.         _fPart = part;
  2777.         ODAcquireObject(ev, _fPart);
  2778.         _fPart->DisplayFrameAdded(ev, somSelf);
  2779.     SOM_CATCH_ALL
  2780.     SOM_ENDTRY
  2781. }
  2782.  
  2783. //------------------------------------------------------------------------------
  2784. // ODFrame: IsMoving
  2785. //------------------------------------------------------------------------------
  2786.  
  2787. SOM_Scope ODBoolean  SOMLINK ODFrameIsMoving(ODFrame *somSelf, Environment *ev)
  2788. {
  2789.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2790.     ODFrameMethodDebug("ODFrame","IsMoving");
  2791.  
  2792.     CHECKVALID(kODFalse);
  2793.     
  2794.     ODBoolean isMoving = _fIsMoving;
  2795.  
  2796.     SOM_TRY
  2797.         if ( !isMoving )
  2798.         {
  2799.             TempODFrame containingFrame = somSelf->AcquireContainingFrame(ev);
  2800.             if ( containingFrame != kODNULL )
  2801.                 isMoving = containingFrame->IsMoving(ev);
  2802.         }
  2803.     SOM_CATCH_ALL_ENDTRY
  2804.  
  2805.     return isMoving;
  2806. }
  2807.  
  2808. //------------------------------------------------------------------------------
  2809. // ODFrame: SetIsMoving
  2810. //------------------------------------------------------------------------------
  2811.  
  2812. SOM_Scope void  SOMLINK ODFrameSetIsMoving(ODFrame *somSelf, Environment *ev,
  2813.         ODBoolean IsMoving)
  2814. {
  2815.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2816.     ODFrameMethodDebug("ODFrame","SetIsMoving");
  2817.  
  2818.     CHECKVALID(VOID);
  2819.     
  2820.     _fIsMoving = IsMoving;
  2821. }
  2822.  
  2823. //------------------------------------------------------------------------------
  2824. // ODFrame: ReleaseAll
  2825. //------------------------------------------------------------------------------
  2826.  
  2827. SOM_Scope void  SOMLINK ODFrameReleaseAll(ODFrame *somSelf, Environment *ev)
  2828. {
  2829.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2830.     ODFrameMethodDebug("ODFrame","ReleaseAll");
  2831.  
  2832.     // *DON'T* CHECKVALID - still need to finalize invalid frames
  2833.     
  2834.     SOM_TRY
  2835.         ODSafeReleaseObject(_fContainingFrame);
  2836.         ODSafeReleaseObject(_fWindow);
  2837.         ODSafeReleaseObject(_fPart);
  2838.  
  2839.         ODSafeReleaseObject(_fFrameShape);
  2840.         ODSafeReleaseObject(_fUsedShape);
  2841.         ODSafeReleaseObject(_fInternalTransform);
  2842.     
  2843.         parent_ReleaseAll(somSelf,ev);
  2844.     SOM_CATCH_ALL
  2845.     SOM_ENDTRY
  2846. }
  2847.  
  2848. //------------------------------------------------------------------------------
  2849. // ODFrame: somUninit
  2850. //------------------------------------------------------------------------------
  2851.  
  2852. SOM_Scope void  SOMLINK ODFramesomUninit(ODFrame *somSelf)
  2853. {
  2854.     ODFrameData *somThis = ODFrameGetData(somSelf);
  2855.     ODFrameMethodDebug("ODFrame","somUninit");
  2856.     
  2857.     ODDeleteObject(_fFacets);
  2858. }
  2859.  
  2860. //------------------------------------------------------------------------------
  2861. // static functions
  2862. //------------------------------------------------------------------------------
  2863.  
  2864. static ODBoolean FrameIsContained( Environment *ev, ODFrame* self,
  2865.         ODFrame* frame )
  2866. {
  2867.     if ( frame == kODNULL )
  2868.         return kODFalse;
  2869.     else if ( ODObjectsAreEqual(ev, self, frame) )
  2870.         return kODTrue;
  2871.     else
  2872.     {
  2873.         TempODFrame parent = frame->AcquireContainingFrame( ev );
  2874.         return FrameIsContained( ev, self, parent );
  2875.     }
  2876. }
  2877.  
  2878.